~ubuntu-branches/ubuntu/lucid/cwdaemon/lucid

« back to all changes in this revision

Viewing changes to patches/cwdaemon-0.7-ok1zia.diff

  • Committer: Bazaar Package Importer
  • Author(s): Joop Stakenborg
  • Date: 2004-04-26 21:27:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040426212729-3wwptnx2a1l9kein
Tags: 0.8
* Cwdaemon is now integrated with unixcw, see cwlib.c and cwlib.h.
  Weighting has been added to unixcw and some special characters needed
  by cwdaemon. The choppiness reported in previous versions of cwdaemon is
  fixed. And we have soundcard support!
* Better handling of aborting messages.
* Weighting now uses a value of -50 to 50.
* 2 extra command line options: -v for volume and -x for sound device.
* 2 extra escape sequences for controlling cwdaemon: ESCfx for switching the
  sound output on the fly and ESCgx for setting the soundcard volume.
* Tune (ESCc) now uses seconds as an argument, e.g. ESCc1 tunes 1 second,
  ESCc10 tunes 10 seconds. Maximum tune value is 10 seconds.
* A fix by Lada, OK1ZIA for big endian systems.
* Footswitch support by Wolf, DL2WRJ (pin 15 of the parallel port).
* New morse character '@' has been added.
* Process priority of cwdaemon can be set with the -P flag. You can try this
  if you experience timing problems.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
diff -ruN cwdaemon-0.7/Makefile.am cwdaemon-0.7-zia/Makefile.am
 
2
--- cwdaemon-0.7/Makefile.am    2003-05-14 19:45:57.000000000 +0200
 
3
+++ cwdaemon-0.7-zia/Makefile.am        2003-11-24 17:39:48.000000000 +0100
 
4
@@ -6,7 +6,7 @@
 
5
 
 
6
 man_MANS = cwdaemon.8
 
7
 
 
8
-cwdaemon_SOURCES = cwdaemon.c cwdaemon.h lp.c ttys.c
 
9
+cwdaemon_SOURCES = cwdaemon.c cwdaemon.h lp.c select.c ttys.c
 
10
 
 
11
 install-data-local:
 
12
        @$(NORMAL_INSTALL)
 
13
diff -ruN cwdaemon-0.7/cwdaemon.c cwdaemon-0.7-zia/cwdaemon.c
 
14
--- cwdaemon-0.7/cwdaemon.c     2003-10-26 20:17:40.000000000 +0100
 
15
+++ cwdaemon-0.7-zia/cwdaemon.c 2003-11-25 12:35:50.000000000 +0100
 
16
@@ -112,10 +112,12 @@
 
17
 int forking = 1;
 
18
 
 
19
 /* network vars */
 
20
-int sin_len;
 
21
+int sin_len, reply_socklen;
 
22
 int socket_descriptor;
 
23
-struct sockaddr_in k_sin;
 
24
+struct sockaddr_in k_sin, reply_sin;
 
25
 int port = 6789;
 
26
+char reply_data[256];
 
27
+int last_id=-1;
 
28
 
 
29
 /* morse defaults */
 
30
 int morse_gap = 0;             /* TODO: Set with -d delay */
 
31
@@ -126,10 +128,7 @@
 
32
 long int dot = 1000000;                /* dot length = unit */
 
33
 long int dash = 3000000;       /* dash length = 3-dot */
 
34
 long int eldelay = 1000000;    /* pause between elements equals to dot time */
 
35
-unsigned int ptt_delay = 0;    /* default = off */
 
36
-
 
37
-/* various variables */
 
38
-int ptt_timer_running = 0;
 
39
+unsigned int ptt_delay = 1000000;      /* default = off */
 
40
 unsigned int bandswitch;
 
41
 
 
42
 struct timeval now, end, left;
 
43
@@ -150,6 +149,7 @@
 
44
 }
 
45
 morse;
 
46
 
 
47
+/* WARNING! Character '^' is used for command 'e' */
 
48
 morse morsetable[] = {
 
49
        {' ', {NIL, NIL, NIL, NIL, NIL, NIL, NIL, NIL}},
 
50
        {'A', {DIH, DAH, NIL, NIL, NIL, NIL, NIL, NIL}},
 
51
@@ -238,6 +238,9 @@
 
52
 cwdevice *cwdev = &cwdevice_ttys;
 
53
 #endif
 
54
 
 
55
+static morse *morse_playing=NULL;
 
56
+static int morse_i=0;
 
57
+
 
58
 /*
 
59
   int weight [-5...0...+5]
 
60
   0 = dot/space ratio 1:3, element space = dot time
 
61
@@ -314,42 +317,6 @@
 
62
                errmsg ("Nanosleep");
 
63
 }
 
64
 
 
65
-/*
 
66
-   this is sample code shameless :-) stolen from
 
67
-   http://www.erlenstar.demon.co.uk/unix/faq_8.html
 
68
-*/
 
69
-
 
70
-/* some simple timing utilities */
 
71
-
 
72
-void
 
73
-timer_add (struct timeval *tv, long secs, long usecs)
 
74
-{
 
75
-       tv->tv_sec += secs;
 
76
-       if ((tv->tv_usec += usecs) >= 1000000)
 
77
-       {
 
78
-               tv->tv_sec += tv->tv_usec / 1000000;
 
79
-               tv->tv_usec %= 1000000;
 
80
-       }
 
81
-}
 
82
-
 
83
-/* Set *RES = *A - *B, returning the sign of the result */
 
84
-
 
85
-int
 
86
-timer_sub (struct timeval *res, const struct timeval *a,
 
87
-          const struct timeval *b)
 
88
-{
 
89
-       long sec = a->tv_sec - b->tv_sec;
 
90
-       long usec = a->tv_usec - b->tv_usec;
 
91
-
 
92
-       if (usec < 0)
 
93
-               usec += 1000000, --sec;
 
94
-
 
95
-       res->tv_sec = sec;
 
96
-       res->tv_usec = usec;
 
97
-
 
98
-       return (sec < 0) ? (-1) : ((sec == 0 && usec == 0) ? 0 : 1);
 
99
-}
 
100
-
 
101
 
 
102
 void
 
103
 set_switch (unsigned int bandswitch)           // band switch function
 
104
@@ -367,82 +334,6 @@
 
105
                debug ("Band switch output not implemented");
 
106
 }
 
107
 
 
108
-void
 
109
-tune (int onoff)
 
110
-{
 
111
-       int fd;
 
112
-
 
113
-       if (onoff)
 
114
-       {
 
115
-               if (ptt_delay)
 
116
-               {
 
117
-                       cwdev->ptt (cwdev, ON);
 
118
-                       debug ("PTT (TUNE) on");
 
119
-                       /* TOD */
 
120
-                       udelay (ptt_delay);
 
121
-               }
 
122
-               cwdev->cw (cwdev, ON);
 
123
-               debug ("CW (TUNE) on");
 
124
-               /* sidetone on if morsetone !=0 */
 
125
-               fd = open ("/dev/tty1", O_WRONLY);
 
126
-               if (fd != -1)
 
127
-               {
 
128
-                       if (ioctl (fd, KIOCSOUND, morse_tone) != 0)
 
129
-                       {
 
130
-                               errmsg ("Ioctl console speaker");
 
131
-                               exit (1);
 
132
-                       }
 
133
-                       close (fd);
 
134
-               }
 
135
-               else
 
136
-               {
 
137
-                       errmsg ("Open console speaker");
 
138
-                       exit (1);
 
139
-               }
 
140
-       }
 
141
-       else
 
142
-       {
 
143
-               if (ptt_delay)
 
144
-               {
 
145
-                       gettimeofday (&end, NULL);
 
146
-                       timer_add (&end, 0, dash / morse_speed);
 
147
-                       ptt_timer_running = 1;
 
148
-               }
 
149
-               cwdev->cw (cwdev, OFF);
 
150
-               debug ("CW (TUNE) off");
 
151
-               fd = open ("/dev/tty1", O_WRONLY);
 
152
-               if (fd != -1)
 
153
-               {
 
154
-                       if (ioctl (fd, KIOCSOUND, 0) != 0)
 
155
-                       {
 
156
-                               errmsg ("Ioctl console speaker");
 
157
-                               exit (1);
 
158
-                       }
 
159
-                       close (fd);
 
160
-               }
 
161
-               else
 
162
-               {
 
163
-                       errmsg ("Open console speaker");
 
164
-                       exit (1);
 
165
-               }
 
166
-               /* delayed ptt off */
 
167
-               if (1 == ptt_timer_running)
 
168
-               {
 
169
-                       while (1)
 
170
-                       {
 
171
-                               udelay (1000);  /*prevent 100% CPU */
 
172
-                               gettimeofday (&now, NULL);
 
173
-                               if (timer_sub (&left, &end, &now) <= 0)
 
174
-                               {
 
175
-                                       cwdev->ptt (cwdev, OFF);
 
176
-                                       debug ("PTT (TUNE) off");
 
177
-                                       ptt_timer_running = 0;
 
178
-                                       break;
 
179
-                               }
 
180
-                       }
 
181
-               }
 
182
-       }
 
183
-}
 
184
 
 
185
 /* convert character to morse by searching the morsetable */
 
186
 morse *
 
187
@@ -459,95 +350,130 @@
 
188
        return (NULL);
 
189
 }
 
190
 
 
191
-/* output to console and serial/parallel port */
 
192
-void
 
193
-playbeep (long duration)
 
194
+
 
195
+
 
196
+void sound(int tone)
 
197
 {
 
198
        int fd;
 
199
 
 
200
-       if (morse_sound)
 
201
+       fd = open ("/dev/tty1", O_WRONLY);
 
202
+       if (fd < 0)
 
203
+    {
 
204
+        errmsg ("Open console speaker");
 
205
+        exit (1);
 
206
+    }
 
207
+    
 
208
+       if (ioctl (fd, KIOCSOUND, tone) != 0)
 
209
        {
 
210
-               signal (SIGINT, SIG_IGN);
 
211
-               signal (SIGQUIT, SIG_IGN);
 
212
-               fd = open ("/dev/tty1", O_WRONLY);
 
213
-               if (fd != -1)
 
214
-               {
 
215
-                       if (ioctl (fd, KIOCSOUND, morse_tone) != 0)
 
216
-                       {
 
217
-                               errmsg ("Ioctl console speaker");
 
218
-                               exit (1);
 
219
-                       }
 
220
-                       close (fd);
 
221
-               }
 
222
-               else
 
223
-               {
 
224
-                       errmsg ("Open console speaker");
 
225
-                       exit (1);
 
226
-               }
 
227
+               errmsg ("Ioctl console speaker");
 
228
+               exit (1);
 
229
        }
 
230
+       close (fd);
 
231
+}
 
232
 
 
233
-       cwdev->cw (cwdev, ON);
 
234
-       udelay (duration / morse_speed);
 
235
 
 
236
-       if (morse_sound)
 
237
-       {
 
238
-               fd = open ("/dev/tty1", O_WRONLY);
 
239
-               if (fd != -1)
 
240
-               {
 
241
-                       if (ioctl (fd, KIOCSOUND, 0) != 0)
 
242
-                       {
 
243
-                               errmsg ("Ioctl console speaker");
 
244
-                               exit (1);
 
245
-                       }
 
246
-                       close (fd);
 
247
-               }
 
248
-               else
 
249
-               {
 
250
-                       errmsg ("Open console speaker");
 
251
-                       exit (1);
 
252
-               }
 
253
-               if (forking)
 
254
-                       signal (SIGINT, SIG_DFL);
 
255
-               else
 
256
-                       signal (SIGINT, catchint);
 
257
-               signal (SIGQUIT, SIG_DFL);
 
258
-       }
 
259
-       cwdev->cw (cwdev, OFF);
 
260
-}
 
261
 
 
262
-/* play dot, dash and use a delay */
 
263
-void
 
264
-playmorse (morse * m)
 
265
+void playmorse (void *xxx)
 
266
 {
 
267
-       int d = 0;
 
268
+    if (!morse_playing) {
 
269
+        debug("playmorse: morse_playing= NULL");
 
270
+        last_id=install_timer(ptt_delay, offdelay, NULL); /* ptt delay can be 0 */
 
271
+        return;
 
272
+    }
 
273
+    debug("playmorse morse_playing='%c' i=%d", morse_playing->code, morse_i);
 
274
+
 
275
+    switch(morse_playing->data[morse_i++]){
 
276
+        case NIL:
 
277
+            debug("     NIL");
 
278
+            get_next_char(); /* NOT first character, we don't need ptt */
 
279
+            last_id=install_timer((dash + ((dot / 10) * morse_gap))/morse_speed, playmorse, NULL);
 
280
+            morse_gap = 0;
 
281
+            break;
 
282
+            
 
283
+        case DIH:
 
284
+            debug("     DIH");
 
285
+               if (morse_sound) sound(morse_tone);
 
286
+               cwdev->cw (cwdev, ON);
 
287
+               last_id=install_timer (dot / morse_speed, playpause, NULL);
 
288
+            break;
 
289
+            
 
290
+        case DAH:
 
291
+            debug("     DAH");
 
292
+               if (morse_sound) sound(morse_tone);
 
293
+               cwdev->cw (cwdev, OFF);
 
294
+               last_id=install_timer (dash / morse_speed, playpause, NULL);
 
295
+            break;
 
296
+    }
 
297
+}
 
298
+
 
299
+void playpause (void *xxx){                      
 
300
+    debug("playpause");
 
301
+
 
302
+       if (morse_sound) sound(0);
 
303
+    if (morse_playing) last_id=install_timer(eldelay/morse_speed, playmorse, NULL);
 
304
+}
 
305
+
 
306
+void pttdelay (void *xxx){
 
307
+    debug("pttdelay");
 
308
+    if (ptt_delay) cwdev->ptt (cwdev, ON);
 
309
+    /* morse_playing and morse_i must be set before */
 
310
+    last_id=install_timer(0, playmorse, NULL);
 
311
+}
 
312
+
 
313
+void offdelay (void *xxx){
 
314
+    debug("offdelay");
 
315
+    if (ptt_delay) cwdev->ptt (cwdev, OFF);
 
316
+       debug ("PTT off");
 
317
+}
 
318
+
 
319
+void tune(int onoff){
 
320
+    debug("tune(%d)", onoff);
 
321
+    if (onoff){
 
322
+        if (ptt_delay) cwdev->ptt (cwdev, ON);
 
323
+        debug ("PTT (TUNE) on");
 
324
+        last_id=install_timer(ptt_delay, tune_pttdelay, NULL); /* ptt_delay can be 0 */
 
325
+    }else{
 
326
+               cwdev->cw (cwdev, OFF);
 
327
+               debug ("CW (TUNE) off");
 
328
+           sound(0);
 
329
+        if (ptt_delay)
 
330
+            last_id=install_timer(dash/morse_speed, tune_offdelay, NULL);    
 
331
+        else
 
332
+            last_id=install_timer(0, tune_offdelay, NULL);    
 
333
+    }
 
334
+}
 
335
+
 
336
+void tune_pttdelay (void *xxx){
 
337
+    debug("tune_pttdelay");
 
338
+    cwdev->cw (cwdev, ON);
 
339
+       debug ("CW (TUNE) on");
 
340
+       if (morse_sound) sound(morse_tone);
 
341
+}
 
342
 
 
343
-       while (d < 8 && m->data[d] != NIL)
 
344
-       {
 
345
-               if (m->data[d] == DIH)
 
346
-                       playbeep (dot);
 
347
-               if (m->data[d] == DAH)
 
348
-                       playbeep (dash);
 
349
-               d++;
 
350
-               udelay (eldelay / morse_speed); /* element spacing */
 
351
-       }                       /* morse signs delay */
 
352
-       udelay ((dash + ((dot / 10) * morse_gap)) / morse_speed);
 
353
-       morse_gap = 0;          /* gap for one sign only */
 
354
+
 
355
+void tune_offdelay (void *xxx){
 
356
+    debug("tune_offdelay");
 
357
+    if (ptt_delay) cwdev->ptt (cwdev, OFF);
 
358
+       debug ("PTT (TUNE) off");
 
359
 }
 
360
 
 
361
+
 
362
+
 
363
 /*
 
364
  * watch the socket and if there is an escape character check what it is,
 
365
  * otherwise play morse. Return 0 with escape characters and empty messages.
 
366
  */
 
367
-int
 
368
-recv_code (void)
 
369
+void recv_code (void *xxx)
 
370
 {
 
371
-       char message[257];
 
372
+       char message1[257];
 
373
+    char *message;
 
374
+    char *token_ptr;
 
375
        ssize_t recv_rc;
 
376
        int speed = 0;
 
377
        int weight = 0;
 
378
 
 
379
        recv_rc =
 
380
-               recvfrom (socket_descriptor, message, sizeof (message) - 1, 0,
 
381
+               recvfrom (socket_descriptor, message1, sizeof (message1) - 1, 0,
 
382
                          (struct sockaddr *) &k_sin, &sin_len);
 
383
 
 
384
        if (recv_rc == -1 && errno != EAGAIN)
 
385
@@ -555,16 +481,21 @@
 
386
                errmsg ("Recvfrom");
 
387
                exit (1);
 
388
        }
 
389
+    
 
390
+    if (recv_rc>=0) message1[recv_rc]='\0';
 
391
 
 
392
-       if (recv_rc > 0)
 
393
-       {
 
394
+    for (message = strtok_r(message1, "\n", &token_ptr); 
 
395
+         message!=NULL; 
 
396
+         message=strtok_r(NULL, "\n", &token_ptr)){
 
397
+    
 
398
                if (message[0] != 27)
 
399
                {               /* no ESCAPE */
 
400
                        message[recv_rc] = '\0';
 
401
-                       debug ("Message: %s, length: %d", message, recv_rc);
 
402
+                       debug ("Message: %s, length: %d", message, strlen(message));
 
403
                        if ((strlen (message) + strlen (morsetext)) <= MAXMORSE - 1)
 
404
                                strcat (morsetext, message);
 
405
-                       return 1;
 
406
+            debug(" Morsetext: %s, length: %d", morsetext, strlen(morsetext));
 
407
+                       continue;
 
408
                }
 
409
                else
 
410
                {               /* check ESCAPE characters */
 
411
@@ -577,6 +508,10 @@
 
412
                                morse_tone = 1500;
 
413
                                morse_sound = 1;
 
414
                                wordmode = 0;
 
415
+                if (last_id>=0) {
 
416
+                    kill_timer(last_id);
 
417
+                    last_id=-1;    
 
418
+                }
 
419
                                cwdev->reset (cwdev);
 
420
                                debug ("Reset all values");
 
421
                                break;
 
422
@@ -704,66 +639,86 @@
 
423
                                        if (bandswitch <= 15 && bandswitch >= 0) 
 
424
             set_switch (bandswitch);
 
425
                                break;
 
426
-                       }
 
427
-                       return 0;
 
428
-               }
 
429
-       }
 
430
-       return 0;
 
431
+            case 'f':   /* send echo to main program when CW playing is done */
 
432
+                memcpy(&reply_sin, &k_sin, sizeof(reply_sin)); /* remember sender */
 
433
+                reply_socklen = sin_len;
 
434
+                strncpy(reply_data, message, sizeof(reply_data) - 1);
 
435
+                reply_data[sizeof(reply_data) - 1] = '\0';
 
436
+                if (strlen (message) + 1 <= MAXMORSE - 1) strcat (morsetext, "^");
 
437
+                break;
 
438
+                       }
 
439
+                       continue;
 
440
+               }
 
441
+        
 
442
+    }
 
443
+    if (!morse_playing) { /* No chars in queue. Maybe active pttoff. We start playing */
 
444
+        get_next_char();
 
445
+        if (ptt_delay){
 
446
+            if (last_id>=0){
 
447
+                kill_timer(last_id);
 
448
+                /* last_id=-1; NO! */
 
449
+            }
 
450
+                       cwdev->ptt (cwdev, ON);
 
451
+            debug("PTT_delay on (%d)", ptt_delay);
 
452
+            if (last_id>=0) /* waiting for pttoff, we don't need pttdelay */
 
453
+                last_id=install_timer(0, playmorse, NULL); /* start immediatelly */
 
454
+            else
 
455
+                last_id=install_timer(ptt_delay,  pttdelay, NULL); /* start after pttdelay */
 
456
+        }else{
 
457
+            last_id=install_timer(0, playmorse, NULL); /* start immediatelly */
 
458
+        }
 
459
+    }
 
460
+
 
461
+       return;
 
462
 }
 
463
 
 
464
+
 
465
+
 
466
 /* check every character for speed increase or decrease, convert other
 
467
-   characters to morse and play them */
 
468
-void
 
469
-playmorsestring (char *x)
 
470
-{
 
471
+   characters to morse and store it into morse_playing and morse_i */
 
472
 
 
473
-       int i = 0;
 
474
-       /* stop ptt timer */
 
475
-       if (ptt_delay)
 
476
-       {
 
477
-               cwdev->ptt (cwdev, ON);
 
478
-               debug ("PTT on");
 
479
-               /* TOD */
 
480
-               udelay (ptt_delay);
 
481
-       }
 
482
-       while (*x)
 
483
-       {
 
484
-               char c = islower (*x) ? toupper (*x) : *x;
 
485
-               if ((c == '+') || (c == '-'))
 
486
-               {               /* speed in- & decrease */
 
487
-                       if ((c == '+') && (morse_speed <= 58))
 
488
-                               morse_speed += 2;
 
489
-                       if ((c == '-') && (morse_speed >= 10))
 
490
-                               morse_speed -= 2;
 
491
-               }
 
492
-               else if (c == '~')
 
493
-                       morse_gap = 15; /* half dash time additional for the next char */
 
494
-               else
 
495
-               {
 
496
-                       morse *m = chartomorse (c);
 
497
-                       if (m != NULL)
 
498
-                               playmorse (m);
 
499
-               }
 
500
-               x++;
 
501
-               i++;
 
502
-               if (i >= strlen (morsetext))
 
503
-               {
 
504
-                       i = 0;
 
505
-                       break;
 
506
-               }
 
507
-               if (wordmode == 0)
 
508
-                       recv_code ();
 
509
-       }
 
510
-       morsetext[0] = '\0';
 
511
-       /* start ptt off timer */
 
512
-       if (ptt_delay)
 
513
-       {
 
514
-               gettimeofday (&end, NULL);
 
515
-               timer_add (&end, 0, dash / morse_speed);
 
516
-               ptt_timer_running = 1;
 
517
-       }
 
518
+void get_next_char(void){
 
519
+    char *x;
 
520
+    
 
521
+    for (x=morsetext; *x!='\0'; x++){
 
522
+        switch(toupper(*x)){
 
523
+            case '+':
 
524
+                if (morse_speed<=58) morse_speed+=2;
 
525
+                break;
 
526
+                
 
527
+            case '-':
 
528
+                if (morse_speed>=10) morse_speed-=2;
 
529
+                break;
 
530
+                
 
531
+            case '~':
 
532
+                morse_gap = 15;        /* half dash time additional for the next char */
 
533
+                break;
 
534
+                
 
535
+            case '^':
 
536
+                if (strlen(reply_data)==0) return;
 
537
+                sendto(socket_descriptor, reply_data, strlen(reply_data), 0, 
 
538
+                    (struct sockaddr *)&reply_sin, reply_socklen);
 
539
+                strcpy(reply_data,"");
 
540
+                break;
 
541
+                
 
542
+            default:            
 
543
+                morse_playing = chartomorse (toupper(*x));
 
544
+                morse_i=0;
 
545
+                if (strlen(morsetext)>0) memmove(morsetext, morsetext+1, strlen(morsetext));
 
546
+                
 
547
+                if (!morse_playing) debug("get_next_char: NULL");
 
548
+                else debug("get_next_char: '%c'", morse_playing->code);
 
549
+                
 
550
+                return;
 
551
+                
 
552
+        }
 
553
+    }
 
554
+    morse_playing = NULL;
 
555
+    morse_i = 0;
 
556
+    return;  /* no morse found */
 
557
 }
 
558
 
 
559
+
 
560
 /* parse the command line and check for options, do some error checking */
 
561
 void
 
562
 parsecommandline (int argc, char *argv[])
 
563
@@ -874,13 +829,30 @@
 
564
        }
 
565
 }
 
566
 
 
567
+void terminate_all_subsystems(void){
 
568
+       int close_rc;
 
569
+
 
570
+    cwdev->free (cwdev);
 
571
+       close_rc = close (socket_descriptor);
 
572
+       if (close_rc == -1)
 
573
+       {
 
574
+               errmsg ("Close socket");
 
575
+               exit (1);
 
576
+       }
 
577
+}
 
578
+
 
579
+void initialize(void){
 
580
+    set_handlers(socket_descriptor, recv_code, NULL, NULL, NULL);
 
581
+}
 
582
+
 
583
+
 
584
 /* main program: fork, open network connection and go into an endless loop
 
585
    waiting for something to happen on the UDP port */
 
586
 int
 
587
 main (int argc, char *argv[])
 
588
 {
 
589
        pid_t pid, sid;
 
590
-       int bind_rc, close_rc;
 
591
+       int bind_rc;
 
592
        long save_file_flags;
 
593
 
 
594
 #ifdef HAVE_LINUX_PPDEV_H
 
595
@@ -961,31 +933,10 @@
 
596
                exit (1);
 
597
        }
 
598
 
 
599
+    
 
600
        morsetext[0] = '\0';
 
601
-       while (1)
 
602
-       {
 
603
-               udelay (1000);  /*prevent 100% CPU */
 
604
-               if (recv_code ())
 
605
-                       playmorsestring (morsetext);
 
606
-               /* check for ptt off timer */
 
607
-               if (1 == ptt_timer_running)
 
608
-               {
 
609
-                       gettimeofday (&now, NULL);
 
610
-                       if (timer_sub (&left, &end, &now) <= 0)
 
611
-                       {
 
612
-                               cwdev->ptt (cwdev, OFF);
 
613
-                               debug ("PTT off");
 
614
-                               ptt_timer_running = 0;
 
615
-                       }
 
616
-               }
 
617
-       }
 
618
+    select_loop(initialize);   
 
619
 
 
620
-       cwdev->free (cwdev);
 
621
-       close_rc = close (socket_descriptor);
 
622
-       if (close_rc == -1)
 
623
-       {
 
624
-               errmsg ("Close socket");
 
625
-               exit (1);
 
626
-       }
 
627
+    terminate_all_subsystems();
 
628
        exit (0);
 
629
 }
 
630
diff -ruN cwdaemon-0.7/cwdaemon.h cwdaemon-0.7-zia/cwdaemon.h
 
631
--- cwdaemon-0.7/cwdaemon.h     2003-10-26 20:18:03.000000000 +0100
 
632
+++ cwdaemon-0.7-zia/cwdaemon.h 2003-11-25 12:07:53.000000000 +0100
 
633
@@ -30,6 +30,27 @@
 
634
 #define MICROPHONE 0
 
635
 #define SOUNDCARD 1
 
636
 
 
637
+#include <errno.h>
 
638
+#include <signal.h>
 
639
+
 
640
+#ifdef HAVE_SYS_TIME_H
 
641
+#include <sys/time.h>
 
642
+#endif
 
643
+
 
644
+#include <sys/types.h>
 
645
+
 
646
+#ifdef HAVE_TIME_H
 
647
+#include <time.h>
 
648
+#endif
 
649
+
 
650
+#ifdef HAVE_SYS_WAIT_H
 
651
+#include <sys/wait.h>
 
652
+#endif
 
653
+
 
654
+#include <stdlib.h>
 
655
+#include <string.h>
 
656
+#include <unistd.h>
 
657
+
 
658
 typedef struct cwdev_s
 
659
 {
 
660
        int (*init) (struct cwdev_s *);
 
661
@@ -47,6 +68,16 @@
 
662
 void errmsg (char *info, ...);
 
663
 void debug (char *info, ...);
 
664
 
 
665
+void get_next_char(void);
 
666
+void playmorse (void *xxx);
 
667
+void playpause (void *xxx);
 
668
+void pttdelay (void *xxx);
 
669
+void offdelay (void *xxx);
 
670
+void tune(int onoff);
 
671
+void tune_pttdelay (void *xxx);
 
672
+void tune_offdelay (void *xxx);
 
673
+
 
674
+       
 
675
 #ifdef HAVE_LINUX_PPDEV_H
 
676
 int lp_init (cwdevice * dev);
 
677
 int lp_free (cwdevice * dev);
 
678
@@ -63,4 +94,88 @@
 
679
 int ttys_cw (cwdevice * dev, int onoff);
 
680
 int ttys_ptt (cwdevice * dev, int onoff);
 
681
 
 
682
+
 
683
+/* select.c */
 
684
+struct list_head {
 
685
+    void *next;
 
686
+    void *prev;
 
687
+};
 
688
+
 
689
+#ifndef HAVE_TYPEOF
 
690
+
 
691
+struct xlist_head {
 
692
+    struct xlist_head *next;
 
693
+    struct xlist_head *prev;
 
694
+};
 
695
+
 
696
+#endif
 
697
+
 
698
+#define init_list(x) {(x).next=&(x); (x).prev=&(x);}
 
699
+#define list_empty(x) ((x).next == &(x))
 
700
+#define del_from_list(x) {((struct list_head *)(x)->next)->prev=(x)->prev; ((struct list_head *)(x)->prev)->next=(x)->next;}
 
701
+/*#define add_to_list(l,x) {(x)->next=(l).next; (x)->prev=(typeof(x))&(l); (l).next=(x); if ((l).prev==&(l)) (l).prev=(x);}*/
 
702
+#define add_at_pos(p,x) do {(x)->next=(p)->next; (x)->prev=(p); (p)->next=(x); (x)->next->prev=(x);} while(0)
 
703
+
 
704
+#ifdef HAVE_TYPEOF
 
705
+#define add_to_list(l,x) add_at_pos((typeof(x))&(l),(x))
 
706
+#define foreach(e,l) for ((e)=(l).next; (e)!=(typeof(e))&(l); (e)=(e)->next)
 
707
+#define foreachback(e,l) for ((e)=(l).prev; (e)!=(typeof(e))&(l); (e)=(e)->prev)
 
708
+#else
 
709
+#define add_to_list(l,x) add_at_pos((struct xlist_head *)(void*)&(l),(struct xlist_head *)(x))
 
710
+#define foreach(e,l) for ((e)=(l).next; (e)!=(void *)&(l); (e)=(e)->next)
 
711
+#define foreachback(e,l) for ((e)=(l).prev; (e)!=(void *)&(l); (e)=(e)->prev)
 
712
+#endif
 
713
+#define free_list(l) {while ((l).next != &(l)) {struct list_head *a=(l).next; del_from_list(a); mem_free(a); }}
 
714
+
 
715
+typedef long ttime;
 
716
+typedef unsigned tcount;
 
717
+
 
718
+extern int terminate;
 
719
+
 
720
+long select_info(int);
 
721
+void select_loop(void (*)());
 
722
+int register_bottom_half(void (*)(void *), void *);
 
723
+void check_bottom_halves();
 
724
+int install_timer(ttime, void (*)(void *), void *);
 
725
+void kill_timer(int);
 
726
+ttime get_timer_time(int);
 
727
+
 
728
+#if 0
 
729
+#define H_READ  0
 
730
+#define H_WRITE 1
 
731
+#define H_ERROR 2
 
732
+#define H_DATA  3
 
733
+
 
734
+void *get_handler(int, int);
 
735
+#endif
 
736
+void set_handlers(int, void (*)(void *), void (*)(void *), void (*)(void *), void *);
 
737
+void install_signal_handler(int, void (*)(void *), void *, int);
 
738
+void set_sigcld();
 
739
+void st_start();
 
740
+void st_stop();
 
741
+
 
742
+extern struct timeval start;
 
743
+#define ST_START gettimeofday(&start, NULL)
 
744
+#define ST_STOP {\
 
745
+    struct timeval stop;\
 
746
+    int sec, usec;\
 
747
+    gettimeofday(&stop, NULL);\
 
748
+    usec=stop.tv_usec-start.tv_usec;\
 
749
+    sec=stop.tv_sec-start.tv_sec;\
 
750
+    if (usec<0){usec+=1000000;sec--;}\
 
751
+    dbg("stopky: %s: %d.%06d \n", __FUNCTION__, sec,usec);\
 
752
+}
 
753
+
 
754
+#define ST_START gettimeofday(&start, NULL)
 
755
+#define ST_STOP {\
 
756
+    struct timeval stop;\
 
757
+    int sec, usec;\
 
758
+    gettimeofday(&stop, NULL);\
 
759
+    usec=stop.tv_usec-start.tv_usec;\
 
760
+    sec=stop.tv_sec-start.tv_sec;\
 
761
+    if (usec<0){usec+=1000000;sec--;}\
 
762
+    dbg("stopky: %s: %d.%06d \n", __FUNCTION__, sec,usec);\
 
763
+}
 
764
+
 
765
+
 
766
 #endif /* _CWDAEMON_H */
 
767
--- cwdaemon-0.7/select.c       1970-01-01 01:00:00.000000000 +0100
 
768
+++ cwdaemon-0.7-zia/select.c   2003-11-25 12:15:59.000000000 +0100
 
769
@@ -0,0 +1,277 @@
 
770
+#include "cwdaemon.h"
 
771
+
 
772
+/*
 
773
+   This file is stolen from links
 
774
+*/   
 
775
+struct timeval start;
 
776
+
 
777
+struct thread {
 
778
+    void (*read_func)(void *);
 
779
+    void (*write_func)(void *);
 
780
+    void (*error_func)(void *);
 
781
+    void *data;
 
782
+};
 
783
+
 
784
+struct thread threads[FD_SETSIZE];
 
785
+
 
786
+fd_set w_read;
 
787
+fd_set w_write;
 
788
+fd_set w_error;
 
789
+
 
790
+fd_set x_read;
 
791
+fd_set x_write;
 
792
+fd_set x_error;
 
793
+
 
794
+int w_max;
 
795
+
 
796
+static int timer_id = 1;
 
797
+
 
798
+struct timer {
 
799
+    struct timer *next;
 
800
+    struct timer *prev;
 
801
+    ttime interval;
 
802
+    void (*func)(void *);
 
803
+    void *data;
 
804
+    int id;
 
805
+};
 
806
+
 
807
+struct list_head timers = {&timers, &timers};
 
808
+
 
809
+ttime get_time()
 
810
+{
 
811
+    struct timeval tv;
 
812
+    gettimeofday(&tv, NULL);
 
813
+    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
 
814
+}
 
815
+
 
816
+struct bottom_half {
 
817
+    struct bottom_half *next;
 
818
+    struct bottom_half *prev;
 
819
+    void (*fn)(void *);
 
820
+    void *data;
 
821
+};
 
822
+
 
823
+struct list_head bottom_halves = { &bottom_halves, &bottom_halves };
 
824
+
 
825
+int register_bottom_half(void (*fn)(void *), void *data)
 
826
+{
 
827
+    struct bottom_half *bh;
 
828
+    foreach(bh, bottom_halves) if (bh->fn == fn && bh->data == data) return 0;
 
829
+    if (!(bh = malloc(sizeof(struct bottom_half)))) return -1;
 
830
+    bh->fn = fn;
 
831
+    bh->data = data;
 
832
+    add_to_list(bottom_halves, bh);
 
833
+    return 0;
 
834
+}
 
835
+
 
836
+void check_bottom_halves()
 
837
+{
 
838
+    struct bottom_half *bh;
 
839
+    void (*fn)(void *);
 
840
+    void *data;
 
841
+    rep:
 
842
+    if (list_empty(bottom_halves)) return;
 
843
+    bh = bottom_halves.prev;
 
844
+    fn = bh->fn;
 
845
+    data = bh->data;
 
846
+    del_from_list(bh);
 
847
+    free(bh);
 
848
+    fn(data);
 
849
+    goto rep;
 
850
+}
 
851
+
 
852
+#define CHK_BH if (!list_empty(bottom_halves)) check_bottom_halves();
 
853
+        
 
854
+ttime last_time;
 
855
+
 
856
+void check_timers()
 
857
+{
 
858
+    ttime interval = get_time() - last_time;
 
859
+    struct timer *t;
 
860
+    foreach(t, timers) t->interval -= interval;
 
861
+    ch:
 
862
+    foreach(t, timers) if (t->interval <= 0) {
 
863
+        struct timer *tt = t;
 
864
+        del_from_list(tt);
 
865
+        tt->func(tt->data);
 
866
+        free(tt);
 
867
+        CHK_BH;
 
868
+        goto ch;
 
869
+    } else break;
 
870
+    last_time += interval;
 
871
+}
 
872
+
 
873
+int install_timer(ttime t, void (*func)(void *), void *data)
 
874
+{
 
875
+    struct timer *tm, *tt;
 
876
+
 
877
+       t/=1000;
 
878
+       //debug("install_timer(%ld.%06ld, %p)", t/1000000, t%1000000, func);
 
879
+    if (!(tm = malloc(sizeof(struct timer)))) return -1;
 
880
+    tm->interval = t;
 
881
+    tm->func = func;
 
882
+    tm->data = data;
 
883
+    tm->id = timer_id++;
 
884
+    foreach(tt, timers) if (tt->interval >= t) break;
 
885
+    add_at_pos(tt->prev, tm);
 
886
+    return tm->id;
 
887
+}
 
888
+
 
889
+ttime get_timer_time(int id)
 
890
+{
 
891
+    struct timer *tm;
 
892
+    foreach(tm, timers) if (tm->id == id) {
 
893
+        return tm->interval;
 
894
+    }
 
895
+    return -1;
 
896
+}
 
897
+
 
898
+
 
899
+void kill_timer(int id)
 
900
+{
 
901
+    struct timer *tm;
 
902
+    int k = 0;
 
903
+    foreach(tm, timers) if (tm->id == id) {
 
904
+        struct timer *tt = tm;
 
905
+        del_from_list(tm);
 
906
+        tm = tm->prev;
 
907
+        free(tt);
 
908
+        k++;
 
909
+    }
 
910
+}
 
911
+
 
912
+
 
913
+void set_handlers(int fd, void (*read_func)(void *), void (*write_func)(void *), void (*error_func)(void *), void *data)
 
914
+{
 
915
+/*    errmsg("set_handlers(%d,%p,%p,%p,%p)\n",fd,read_func,write_func,error_func,data);*/
 
916
+    
 
917
+    if (fd < 0 || fd >= FD_SETSIZE) {
 
918
+        return;
 
919
+    }
 
920
+    threads[fd].read_func = read_func;
 
921
+    threads[fd].write_func = write_func;
 
922
+    threads[fd].error_func = error_func;
 
923
+    threads[fd].data = data;
 
924
+    if (read_func) FD_SET(fd, &w_read);
 
925
+    else {
 
926
+        FD_CLR(fd, &w_read);
 
927
+        FD_CLR(fd, &x_read);
 
928
+    }
 
929
+    if (write_func) FD_SET(fd, &w_write);
 
930
+    else {
 
931
+        FD_CLR(fd, &w_write);
 
932
+        FD_CLR(fd, &x_write);
 
933
+    }
 
934
+    if (error_func) FD_SET(fd, &w_error);
 
935
+    else {
 
936
+        FD_CLR(fd, &w_error);
 
937
+        FD_CLR(fd, &x_error);
 
938
+    }
 
939
+    if (read_func || write_func || error_func) {
 
940
+        if (fd >= w_max) w_max = fd + 1;
 
941
+    } else if (fd == w_max - 1) {
 
942
+        int i;
 
943
+        for (i = fd - 1; i >= 0; i--)
 
944
+            if (FD_ISSET(i, &w_read) || FD_ISSET(i, &w_write) ||
 
945
+                FD_ISSET(i, &w_error)) break;
 
946
+        w_max = i + 1;
 
947
+    }
 
948
+}
 
949
+
 
950
+
 
951
+int terminate = 0;
 
952
+
 
953
+void select_loop(void (*init)())
 
954
+{
 
955
+    FD_ZERO(&w_read);
 
956
+    FD_ZERO(&w_write);
 
957
+    FD_ZERO(&w_error);
 
958
+    w_max = 0;
 
959
+    last_time = get_time();
 
960
+    signal(SIGPIPE, SIG_IGN);
 
961
+    if (init) init();
 
962
+    CHK_BH;
 
963
+    while (!terminate) {
 
964
+        int n, i;
 
965
+        struct timeval tv;
 
966
+        struct timeval *tm = NULL;
 
967
+        check_timers();
 
968
+        if (!list_empty(timers)) {
 
969
+            ttime tt = ((struct timer *)(void*)&timers)->next->interval + 1;
 
970
+            if (tt < 0) tt = 0;
 
971
+            tv.tv_sec = tt / 1000;
 
972
+            tv.tv_usec = (tt % 1000) * 1000;
 
973
+            tm = &tv;
 
974
+        }
 
975
+        memcpy(&x_read, &w_read, sizeof(fd_set));
 
976
+        memcpy(&x_write, &w_write, sizeof(fd_set));
 
977
+        memcpy(&x_error, &w_error, sizeof(fd_set));
 
978
+        if (terminate) break;
 
979
+        if (!w_max && list_empty(timers)) break;
 
980
+        CHK_BH;
 
981
+
 
982
+/*             if (tm) debug("select() tm=%ld.%06ld", tm->tv_sec, tm->tv_usec);*/
 
983
+        n = select(w_max, &x_read, &x_write, &x_error, tm);
 
984
+        if (n < 0) {
 
985
+            if (errno != EINTR) {
 
986
+                errmsg("ERROR: select failed: %d", errno);
 
987
+                if (errno == EBADF){
 
988
+                    int i;
 
989
+                    fd_set x;
 
990
+                    struct timeval tv;
 
991
+                    
 
992
+                    errmsg("\nR:");
 
993
+                    for (i = 0; i < 256; i++) if (FD_ISSET(i, &x_read)) errmsg("%d,", i);
 
994
+                    errmsg("\nW:");
 
995
+                    for (i = 0; i < 256; i++) if (FD_ISSET(i, &x_write)) errmsg("%d,", i);
 
996
+                    errmsg("\nE:");
 
997
+                    for (i = 0; i < 256; i++) if (FD_ISSET(i, &x_error)) errmsg("%d,", i);
 
998
+                    errmsg("\n_:");
 
999
+
 
1000
+                    for (i = 0; i < 256; i++) {
 
1001
+                        FD_ZERO(&x);
 
1002
+                        FD_SET(i, &x);
 
1003
+                        tv.tv_sec=0;
 
1004
+                        tv.tv_usec=1;
 
1005
+                        if (select(i+1, &x, NULL, NULL, &tv)==0) 
 
1006
+                            errmsg("%d,", i);
 
1007
+                    }
 
1008
+                    
 
1009
+                    errmsg("DIE\n");
 
1010
+                    raise(SIGSEGV);
 
1011
+                }
 
1012
+            }
 
1013
+            
 
1014
+            continue;
 
1015
+        }
 
1016
+        check_timers();
 
1017
+        i = -1;
 
1018
+        while (n > 0 && ++i < w_max) {
 
1019
+            int k = 0;
 
1020
+            if (FD_ISSET(i, &x_read)) {
 
1021
+                if (threads[i].read_func) {
 
1022
+                    threads[i].read_func(threads[i].data);
 
1023
+                    CHK_BH;
 
1024
+                }
 
1025
+                k = 1;
 
1026
+            }
 
1027
+            if (FD_ISSET(i, &x_write)) {
 
1028
+                if (threads[i].write_func) {
 
1029
+                    threads[i].write_func(threads[i].data);
 
1030
+                    CHK_BH;
 
1031
+                }
 
1032
+                k = 1;
 
1033
+            }
 
1034
+            if (FD_ISSET(i, &x_error)) {
 
1035
+                if (threads[i].error_func) {
 
1036
+                    threads[i].error_func(threads[i].data);
 
1037
+                    CHK_BH;
 
1038
+                }
 
1039
+                k = 1;
 
1040
+            }
 
1041
+            n -= k;
 
1042
+        }
 
1043
+    }
 
1044
+
 
1045
+}
 
1046
+