source: trunk/com-on-air_cs-linux/tools/dect_cli.c @ 44

Last change on this file since 44 was 44, checked in by krater, 11 years ago

descrambling bug fixed

File size: 18.4 KB
Line 
1/*
2 * dect_cli async and sync interface to DECT, can dump pcap files
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * authors:
9 * (C) 2008  Matthias Wenzel <dect at mazzoo dot de>
10 * (C) 2008  Andreas Schuler <krater at badterrorist dot com>
11 *
12 */
13
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <fcntl.h>
17#include <stdio.h>
18#include <string.h>
19#include <errno.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <stdint.h>
23#include <sys/ioctl.h>
24#include <time.h>
25#include <limits.h>
26#include <signal.h>
27#include <ctype.h>
28#include <pcap.h>
29
30
31#include "com_on_air_user.h"
32#include "dect_cli.h"
33
34struct cli_info cli;
35
36
37#define  RXBUF 8192
38char buf[RXBUF];
39
40
41/* pcap errors */
42char errbuf[PCAP_ERRBUF_SIZE];
43
44int rfpi_is_ignored(const uint8_t * RFPI);
45
46void print_help(void)
47{
48        LOG("\n");
49        LOG("   help          - this help\n");
50        LOG("   fpscan        - async scan for basestations, dump RFPIs\n");
51        LOG("   callscan      - async scan for active calls, dump RFPIs\n");
52        LOG("   autorec       - sync on any calls in callscan, autodump in pcap\n");
53        LOG("   ppscan <rfpi> - sync scan for active calls\n");
54        LOG("   chan <ch>     - set current channel [0-9], currently %d\n", cli.channel);
55//      LOG("   slot <sl>     - set current slot [0-23], currently %d\n", cli.slot);
56//      LOG("   jam           - jam current channel\n");
57        LOG("   band          - toggle between EMEA/DECT and US/DECT6.0 bands\n");
58        LOG("   ignore <rfpi> - toggle ignoring of an RFPI in autorec\n");
59        LOG("   dump          - dump stations and calls we have seen\n");
60        LOG("   hop           - toggle channel hopping, currently %s\n", cli.hop ? "ON":"OFF");
61        LOG("   verb          - toggle verbosity, currently %s\n", cli.verbose ? "ON":"OFF");
62        LOG("   stop          - stop it - whatever we were doing\n");
63        LOG("   quit          - well :)\n");
64        LOG("\n");
65}
66
67void set_channel(uint32_t channel)
68{
69        if (cli.verbose)
70                LOG("### switching to channel %d\n", ch2etsi[channel]);
71        if (ioctl(cli.fd, COA_IOCTL_CHAN, &ch2etsi[channel])){
72                LOG("!!! couldn't ioctl()\n");
73                exit(1);
74        }
75        cli.last_hop = time(NULL);
76}
77
78void set_slot(uint32_t slot)
79{
80        LOG("!!! not yet implemented :(\n");
81}
82
83void do_ppscan(uint8_t * RFPI)
84{
85        LOG("### trying to sync on %.2x %.2x %.2x %.2x %.2x\n",
86                RFPI[0],
87                RFPI[1],
88                RFPI[2],
89                RFPI[3],
90                RFPI[4]
91           );
92
93        /* set sync sniff mode */
94        uint16_t val;
95        val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SYNC;
96        if (ioctl(cli.fd, COA_IOCTL_MODE, &val)){
97                LOG("!!! couldn't ioctl()\n");
98                exit(1);
99        }
100
101        /* set rfpi to sync with */
102        if(ioctl(cli.fd, COA_IOCTL_SETRFPI, RFPI)){
103                LOG("!!! couldn't ioctl()\n");
104                exit(1);
105        }
106
107        set_channel(cli.channel);
108
109        memcpy(cli.RFPI, RFPI, 5);
110        cli.mode = MODE_PPSCAN;
111
112        cli.autorec_last_bfield = time(NULL);
113}
114
115void add_station(struct dect_station * station)
116{
117        int i;
118        LOG("### found new %s", station->type == TYPE_FP ? "station":"call on");
119        for (i=0; i<5; i++)
120                LOG(" %.2x", station->RFPI[i]);
121        LOG(" on channel %d RSSI %d\n", station->channel, station->RSSI);
122
123        struct dect_station * p = cli.station_list;
124        if (p)
125        { /* append to existing list */
126                while (p->next)
127                        p = p->next;
128                p->next = malloc(sizeof(*p));
129                p = p->next;
130        }else /* create 1st element in list */
131        {
132                cli.station_list = malloc(sizeof(*cli.station_list));
133                p = cli.station_list;
134        }
135        if (!p)
136        {
137                LOG("!!! out of memory\n");
138                exit(1);
139        }
140        memset(p, 0, sizeof(*p));
141
142        memcpy(p->RFPI, station->RFPI, 5);
143        p->channel = station->channel;
144        p->RSSI = station->RSSI;
145        p->type = station->type;
146        p->first_seen = time(NULL);
147        p->last_seen = p->first_seen;
148        p->count_seen = 1;
149}
150
151void try_add_station(struct dect_station * station)
152{
153        struct dect_station * p = cli.station_list;
154        int found = 0;
155        while (p)
156        {
157                if (!memcmp(p->RFPI, station->RFPI, 5))
158                {
159                        if (p->type == station->type)
160                        {
161                                if ( (p->channel != station->channel) &&
162                                                (cli.verbose) )
163                                {
164                                        int i;
165                                        LOG("### station");
166                                        for (i=0; i<5; i++)
167                                                LOG(" %.2x", station->RFPI[i]);
168                                        LOG(" switched from channel %d to channel %d\n",
169                                                        p->channel,
170                                                        station->channel);
171                                }
172                                found = 1;
173                                p->channel = station->channel;
174                                p->count_seen++;
175                                p->last_seen = time(NULL);
176                                p->RSSI += station->RSSI; /* we avg on dump */
177                        }
178                }
179                p = p->next;
180        }
181        if (!found)
182                add_station(station);
183        if (cli.autorec && (cli.mode != MODE_PPSCAN))
184        {
185                if (rfpi_is_ignored(station->RFPI))
186                {
187                        if (cli.verbose)
188                        {
189                                LOG("### skipping ignored RFPI %.2x %.2x %.2x %.2x %.2x\n",
190                                                station->RFPI[0], station->RFPI[1], station->RFPI[2],
191                                                station->RFPI[3], station->RFPI[4]);
192                        }
193                }
194                else
195                {
196                        do_ppscan(station->RFPI);
197                }
198        }
199}
200
201
202void do_fpscan(void)
203{
204        LOG("### starting fpscan\n");
205        uint16_t val;
206        val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SCANFP;
207        if (ioctl(cli.fd, COA_IOCTL_MODE, &val)){
208                LOG("!!! couldn't ioctl()\n");
209                exit(1);
210        }
211        /* set start channel */
212        set_channel(cli.channel);
213        cli.mode = MODE_FPSCAN;
214        cli.autorec = 0;
215}
216
217void do_callscan(void)
218{
219        LOG("### starting callscan\n");
220        uint16_t val;
221        val = COA_MODE_SNIFF | COA_SUBMODE_SNIFF_SCANPP;
222        if (ioctl(cli.fd, COA_IOCTL_MODE, &val)){
223                LOG("!!! couldn't ioctl()\n");
224                exit(1);
225        }
226        /* set start channel */
227        set_channel(cli.channel);
228        cli.mode = MODE_CALLSCAN;
229}
230
231int hexvalue(int hexdigit)
232{
233        if (hexdigit >= '0' && hexdigit <= '9')
234                return hexdigit - '0';
235        if (hexdigit >= 'a' && hexdigit <= 'f')
236                return hexdigit - ('a' - 10);
237        if (hexdigit >= 'A' && hexdigit <= 'F')
238                return hexdigit - ('A' - 10);
239        return -1;
240}
241
242int parse_rfpi(const char * str_rfpi, uint8_t * rfpi)
243{
244        int i = 0;
245
246        // Skip initial whitespace:
247        while (isspace(*str_rfpi))
248                str_rfpi++;
249
250        for (;;)
251        {
252                int highnibble, lownibble;
253                highnibble = hexvalue(str_rfpi[0]);
254                // Need to check for validity of the first character before
255                // continuing with the next, in case the first one was \0:
256                if (highnibble == -1)
257                        return -1;
258                lownibble = hexvalue(str_rfpi[1]);
259                if (lownibble == -1)
260                        return -1;
261                rfpi[i] = (highnibble << 4) | lownibble;
262               
263                if (i == 4)
264                        break;
265                i++;
266                str_rfpi += 2;
267
268                // Accept space or colon as byte separator. None at all is ok too.
269                if (*str_rfpi == ' ' || *str_rfpi == ':')
270                        str_rfpi++;
271        }
272
273        return 0;
274}
275
276void do_ppscan_str(char * str_rfpi)
277{
278        uint8_t RFPI[5];
279
280        if (parse_rfpi(str_rfpi, RFPI) == -1)
281        {
282                LOG("!!! please enter a valid RFPI (e.g. 00 01 02 03 04)\n");
283                return;
284        }
285        do_ppscan(RFPI);
286}
287
288// Returns true if 'RFPI' occurs in 'list'.
289int rfpi_list_present(struct rfpi_list * list, const uint8_t * RFPI)
290{
291        for (; list != NULL; list = list->next)
292        {
293                if (!memcmp(RFPI, list->RFPI, 5))
294                        return 1;
295        }
296        return 0;
297}
298
299// Adds 'RFPI' at the front of '*list_ptr'.
300void rfpi_list_add(struct rfpi_list ** list_ptr, const uint8_t * RFPI)
301{
302        struct rfpi_list * new_link = malloc(sizeof (struct rfpi_list));
303        memcpy(new_link->RFPI, RFPI, 5);
304        new_link->next = *list_ptr;
305        *list_ptr = new_link;
306}
307
308// Removes the first occurence of 'RFPI' from '*list_ptr'.
309void rfpi_list_remove(struct rfpi_list ** list_ptr, const uint8_t * RFPI)
310{
311        for (; *list_ptr != NULL; list_ptr = &(*list_ptr)->next)
312        {
313                struct rfpi_list * link = *list_ptr;
314                if (!memcmp(RFPI, link->RFPI, 5))
315                {
316                        *list_ptr = link->next;
317                        free(link);
318                        return;
319                }
320        }
321}
322
323int rfpi_is_ignored(const uint8_t * RFPI)
324{
325        return rfpi_list_present(cli.ignored_rfpis, RFPI);
326}
327
328void rfpi_ignore_rfpi(const uint8_t * RFPI)
329{
330        rfpi_list_add(&cli.ignored_rfpis, RFPI);
331}
332
333void rfpi_unignore_rfpi(const uint8_t * RFPI)
334{
335        rfpi_list_remove(&cli.ignored_rfpis, RFPI);
336}
337
338void do_ignore_str(const char * str_rfpi)
339{
340        uint8_t RFPI[5];
341
342        if (parse_rfpi(str_rfpi, RFPI) == -1)
343        {
344                LOG("!!! please enter a valid RFPI (e.g. 00 01 02 03 04)\n");
345                return;
346        }
347
348        if (rfpi_is_ignored(RFPI))
349        {
350                LOG("### no longer ignoring RFPI %.2x %.2x %.2x %.2x %.2x\n",
351                                RFPI[0], RFPI[1], RFPI[2], RFPI[3], RFPI[4]);
352                rfpi_unignore_rfpi(RFPI);
353        }
354        else
355        {
356                LOG("### ignoring RFPI %.2x %.2x %.2x %.2x %.2x\n",
357                                RFPI[0], RFPI[1], RFPI[2], RFPI[3], RFPI[4]);
358                rfpi_ignore_rfpi(RFPI);
359        }
360}
361
362
363void do_chan(char * str_chan)
364{
365        uint32_t channel;
366        char * end;
367        errno = 0;
368        channel = strtoul(str_chan, &end, 0);
369        if ((errno == ERANGE && (channel == LONG_MAX || channel == LONG_MIN))
370                        || (errno != 0 && channel == 0))
371        {
372                LOG("!!! please enter a valid channel number [0-14]\n");
373                return;
374        }
375        if (end == str_chan)
376        {
377                LOG("!!! please enter a valid channel number [0-14]\n");
378                return;
379        }
380        if (! ((channel >=  0) && (channel <= 14)) )
381        {
382                LOG("!!! please enter a valid channel number [0-14]\n");
383                return;
384        }
385        cli.channel = channel;
386        set_channel(cli.channel);
387}
388
389void do_slot(char * str_slot)
390{
391        uint32_t slot;
392        char * end;
393        errno = 0;
394        slot = strtoul(str_slot, &end, 0);
395        if ((errno == ERANGE && (slot == LONG_MAX || slot == LONG_MIN))
396                        || (errno != 0 && slot == 0))
397        {
398                LOG("!!! please enter a valid slot number [0-23]\n");
399                return;
400        }
401        if (end == str_slot)
402        {
403                LOG("!!! please enter a valid slot number [0-23]\n");
404                return;
405        }
406        if (slot > 23)
407        {
408                LOG("!!! please enter a valid slot number [0-23]\n");
409                return;
410        }
411        cli.slot = slot;
412        set_slot(cli.slot);
413}
414
415void do_jam(void)
416{
417        LOG("!!! not yet implemented :(\n");
418}
419
420void do_band(void)
421{
422        switch (cli.band)
423        {
424                case DECT_BAND_EMEA:
425                        cli.band      = DECT_BAND_US;
426                        cli.hop_start = 10;
427                        cli.hop_end   = 14;
428                        cli.channel   = cli.hop_start;
429                        LOG("### using US/DECT6.0 band\n");
430                        break;
431                case DECT_BAND_US:
432                        cli.band      = DECT_BAND_EMEA | DECT_BAND_US;
433                        cli.hop_start = 0;
434                        cli.hop_end   = 14;
435                        cli.channel   = cli.hop_start;
436                        LOG("### using both EMEA/DECT and US/DECT6.0 band\n");
437                        break;
438                case DECT_BAND_EMEA | DECT_BAND_US:
439                        cli.band      = DECT_BAND_EMEA;
440                        cli.hop_start = 0;
441                        cli.hop_end   = 9;
442                        cli.channel   = cli.hop_start;
443                        LOG("### using EMEA/DECT band\n");
444                        break;
445        }
446
447}
448
449void do_dump(void)
450{
451        int i;
452        struct dect_station * p = cli.station_list;
453        struct rfpi_list * r = cli.ignored_rfpis;
454        if (!p)
455        {
456                LOG("### nothing found so far\n");
457                goto dump_ignore;
458        }
459
460        LOG("### stations\n");
461        do
462        {
463                if (p->type == TYPE_FP)
464                {
465                        LOG("   ");
466                        for (i=0; i<5; i++)
467                                LOG(" %.2x", p->RFPI[i]);
468                        LOG("  ch %1.1d ", p->channel);
469                        LOG(" RSSI %5.2f ", (double)p->RSSI / p->count_seen);
470                        LOG(" count %4.u ", p->count_seen);
471                        LOG(" first %u ", p->first_seen);
472                        LOG(" last %u ", p->last_seen);
473                        LOG("\n");
474                }
475        } while ((p = p->next));
476
477        p = cli.station_list;
478        LOG("### calls\n");
479        do
480        {
481                if (p->type == TYPE_PP)
482                {
483                        LOG("   ");
484                        for (i=0; i<5; i++)
485                                LOG(" %.2x", p->RFPI[i]);
486                        LOG("  ch %1.1d ", p->channel);
487                        LOG(" RSSI %5.2f ", (double)p->RSSI / p->count_seen);
488                        LOG(" count %4.u ", p->count_seen);
489                        LOG(" first %u ", p->first_seen);
490                        LOG(" last %u ", p->last_seen);
491                        LOG("\n");
492                }
493        } while ((p = p->next));
494
495dump_ignore:
496        if (!r)
497                return;
498
499        LOG("### RFPIs ignored\n");
500        do{
501                LOG("   %.2x %.2x %.2x %.2x %.2x is ignored\n",
502                        r->RFPI[0],
503                        r->RFPI[1],
504                        r->RFPI[2],
505                        r->RFPI[3],
506                        r->RFPI[4]
507                        );
508        } while ((r = r->next));
509}
510
511void do_hop(void)
512{
513        cli.hop = cli.hop ? 0:1;
514        LOG("### channel hopping turned %s\n", cli.hop ? "ON":"OFF");
515}
516
517void do_verb(void)
518{
519        cli.verbose = cli.verbose ? 0:1;
520        LOG("### verbosity turned %s\n", cli.verbose ? "ON":"OFF");
521}
522
523void do_autorec(void)
524{
525        cli.autorec = cli.autorec ? 0:1;
526        LOG("### starting autorec\n");
527}
528
529void do_stop_keep_autorec(void)
530{
531        LOG("### stopping DIP\n");
532        uint16_t val;
533        val = COA_MODE_IDLE;
534        if (ioctl(cli.fd, COA_IOCTL_MODE, &val)){
535                LOG("couldn't ioctl()\n");
536                exit(1);
537        }
538        cli.mode = MODE_STOP;
539}
540
541void do_stop(void)
542{
543        if (!(cli.mode & MODE_STOP))
544        {
545                do_stop_keep_autorec();
546        }
547        cli.autorec = 0;
548}
549
550void do_quit(void)
551{
552        do_stop();
553        do_dump();
554        exit(0);
555}
556
557void process_cli_data()
558{
559        int ret;
560        ret = read(cli.in, buf, RXBUF);
561        buf[ret]=0;
562        if(buf[ret-1] == '\n')
563                buf[ret-1] = 0;
564        int done = 0;
565        if ( !strncasecmp((char *)buf, "help", 4) )
566                { print_help(); done = 1; }
567        if ( !strncasecmp((char *)buf, "fpscan", 6) )
568                { do_fpscan(); done = 1; }
569        if ( !strncasecmp((char *)buf, "callscan", 8) )
570                { do_callscan(); done = 1; }
571        if ( !strncasecmp((char *)buf, "autorec", 7) )
572                { do_autorec(); done = 1; }
573        if ( !strncasecmp((char *)buf, "ppscan", 6) )
574                { do_ppscan_str(&buf[6]); done = 1; }
575        if ( !strncasecmp((char *)buf, "chan", 4) )
576                { do_chan(&buf[4]); done = 1; }
577        if ( !strncasecmp((char *)buf, "slot", 4) )
578                { do_slot(&buf[4]); done = 1; }
579        if ( !strncasecmp((char *)buf, "jam", 3) )
580                { do_jam(); done = 1; }
581        if ( !strncasecmp((char *)buf, "band", 4) )
582                { do_band(); done = 1; }
583        if ( !strncasecmp((char *)buf, "ignore", 6) )
584                { do_ignore_str(&buf[6]); done = 1; }
585        if ( !strncasecmp((char *)buf, "dump", 4) )
586                { do_dump(); done = 1; }
587        if ( !strncasecmp((char *)buf, "hop", 3) )
588                { do_hop(); done = 1; }
589        if ( !strncasecmp((char *)buf, "verb", 4) )
590                { do_verb(); done = 1; }
591        if ( !strncasecmp((char *)buf, "stop", 4) )
592                { do_stop(); done = 1; }
593        if ( !strncasecmp((char *)buf, "quit", 4) )
594                do_quit();
595
596        if(!done)
597                LOG("!!! no such command %s\n", buf);
598
599}
600
601void init_pcap(struct sniffed_packet * packet)
602{
603        char fname[512];
604        char ftime[256];
605        time_t rawtime;
606        struct tm *timeinfo;
607
608        time (&rawtime);
609        timeinfo = localtime(&rawtime);
610
611        strftime(ftime, sizeof(ftime), "%Y-%m-%d_%H_%M_%S", timeinfo);
612
613        sprintf(fname, "dump_%s_RFPI_%.2x_%.2x_%.2x_%.2x_%.2x.pcap",
614                        ftime,
615                        cli.RFPI[0],
616                        cli.RFPI[1],
617                        cli.RFPI[2],
618                        cli.RFPI[3],
619                        cli.RFPI[4]);
620        LOG("### dumping to %s\n", fname);
621        cli.pcap = pcap_open_dead(DLT_EN10MB, 73);
622        if (!cli.pcap)
623        {
624                LOG("!!! couldn't pcap_open_dead(\"%s\")\n", fname);
625        }
626        cli.pcap_d = pcap_dump_open(cli.pcap, fname);
627        if (!cli.pcap_d)
628        {
629                LOG("!!! couldn't pcap_dump_open(\"%s\")\n", fname);
630        }
631}
632
633int has_b_field()
634{
635        if ((cli.packet.data[5] & 0x0e) != 0x0e)
636                return 1;
637        return 0;
638}
639
640void process_dect_data()
641{
642        int ret;
643        switch (cli.mode)
644        {
645                case MODE_FPSCAN:
646                        while (7 == (ret = read(cli.fd, buf, 7))){
647                                memcpy(cli.station.RFPI, &buf[2], 5);
648                                cli.station.channel = buf[0];
649                                cli.station.RSSI = buf[1];
650                                cli.station.type = TYPE_FP;
651                                try_add_station(&cli.station);
652                        }
653                        break;
654                case MODE_CALLSCAN:
655                        while (7 == (ret = read(cli.fd, buf, 7))){
656                                memcpy(cli.station.RFPI, &buf[2], 5);
657                                cli.station.channel = buf[0];
658                                cli.station.RSSI = buf[1];
659                                cli.station.type = TYPE_PP;
660                                try_add_station(&cli.station);
661                        }
662                        break;
663                case MODE_PPSCAN:
664                        while ( sizeof(cli.packet) ==
665                                read(cli.fd, &cli.packet, sizeof(cli.packet)))
666                        {
667                                memcpy(cli.station.RFPI, cli.RFPI, 5);
668                                cli.station.channel = cli.packet.channel;
669                                cli.station.RSSI = cli.packet.rssi;
670                                cli.station.type = TYPE_PP;
671                                /* to ypdate statistics only we try_add_station() */
672                                try_add_station(&cli.station);
673
674                                /* stop hopping once we're synchronized */
675                                cli.hop = 0;
676
677                                if (!cli.pcap)
678                                {
679                                        LOG("### got sync\n");
680                                        init_pcap(&cli.packet);
681                                        /* this is not actually a B-Field,
682                                         * but we expect some to come soon
683                                         * and the val needs to be non-0 */
684                                        cli.autorec_last_bfield = time(NULL);
685                                }
686                                if (has_b_field())
687                                        cli.autorec_last_bfield = time(NULL);
688
689                                struct pcap_pkthdr pcap_hdr;
690                                pcap_hdr.caplen = 73;
691                                pcap_hdr.len = 73;
692                                ret = gettimeofday(&pcap_hdr.ts, NULL);
693                                if (ret)
694                                {
695                                        LOG("!!! couldn't gettimeofday(): %s\n",
696                                                        strerror(errno));
697                                        exit(1);
698                                }
699                                uint8_t pcap_packet[100];
700                                memset(pcap_packet, 0, 100);
701                                pcap_packet[12] = 0x23;
702                                pcap_packet[13] = 0x23;
703                                pcap_packet[14] = 0x00;        /* decttype (receive) */
704                                pcap_packet[15] = cli.packet.channel;
705                                pcap_packet[16] = 0x00;
706                                pcap_packet[17] = cli.packet.slot;
707                                pcap_packet[18] = cli.packet.framenumber;
708                                pcap_packet[19] = cli.packet.rssi;
709                                memcpy(&pcap_packet[20], cli.packet.data, 53);
710
711                                pcap_dump(cli.pcap_d, &pcap_hdr, pcap_packet);
712                        }
713                        break;
714        }
715}
716
717void init_dect()
718{
719        cli.fd = open(DEV, O_RDWR | O_NONBLOCK);
720        if (cli.fd < 0)
721        {
722                LOG("!!! couldn't open(\"%s\"): %s\n",
723                                DEV,
724                                strerror(errno));
725                exit(1);
726        }
727        cli.pcap = NULL;
728}
729
730void signal_handler(int s)
731{
732        LOG("### got signal %d, will dump & quit\n", s);
733        do_quit();
734}
735
736void init_cli()
737{
738        cli.channel      = 0;
739        cli.slot         = 0;
740        cli.hop          = 1;
741        cli.hop_ch_time  = 1; /* in sec */
742
743        cli.mode         = MODE_STOP;
744
745        cli.in           = fileno(stdin);
746
747        cli.verbose      = 0;
748
749        cli.station_list = NULL;
750        cli.ignored_rfpis= NULL;
751
752        cli.autorec             = 0;
753        cli.autorec_timeout     = 10;
754        cli.autorec_last_bfield = 0;
755
756        cli.band                = DECT_BAND_EMEA;
757        cli.hop_start           = 0;
758        cli.hop_end             = 9;
759
760        signal(SIGHUP, signal_handler);
761        signal(SIGINT, signal_handler);
762        signal(SIGQUIT, signal_handler);
763        signal(SIGABRT, signal_handler);
764        signal(SIGKILL, signal_handler);
765        signal(SIGALRM, signal_handler);
766        signal(SIGTERM, signal_handler);
767        signal(SIGUSR1, signal_handler);
768        signal(SIGUSR2, signal_handler);
769}
770
771void init(void)
772{
773        init_dect();
774        init_cli();
775}
776
777int max_int(int a, int b)
778{
779        if (a>b)
780                return a;
781        else
782                return b;
783}
784
785void mainloop(void)
786{
787        fd_set rfd;
788        fd_set wfd;
789        fd_set efd;
790
791        int nfds = max_int(cli.in, cli.fd);
792        nfds++;
793
794        struct timeval tv;
795
796        int ret;
797
798        while (0xDEC + 'T')
799        {
800                tv.tv_sec  = 1;
801                tv.tv_usec = 0;
802
803                FD_ZERO(&rfd);
804                FD_ZERO(&wfd);
805                FD_ZERO(&efd);
806
807                FD_SET(cli.in, &rfd);
808                FD_SET(cli.fd, &rfd);
809
810                FD_SET(cli.in, &efd);
811                FD_SET(cli.fd, &efd);
812
813                ret = select(nfds, &rfd, &wfd, &efd, &tv);
814                if (ret < 0)
815                {
816                        LOG("!!! select()\n");
817                        exit(1);
818                }
819                if (FD_ISSET(cli.in, &efd))
820                {
821                        LOG("!!! select() on in: %s\n",
822                                        strerror(errno));
823                        exit(1);
824                }
825                if (FD_ISSET(cli.fd, &efd))
826                {
827                        LOG("!!! select() on fd: %s\n",
828                                        strerror(errno));
829                        exit(1);
830                }
831
832                if (FD_ISSET(cli.in, &rfd))
833                        process_cli_data();
834                if (FD_ISSET(cli.fd, &rfd))
835                        process_dect_data();
836
837                if( (cli.hop) &&
838                                ( (cli.mode & MODE_FPSCAN) ||
839                                  (cli.mode & MODE_PPSCAN) ||
840                                  (cli.mode & MODE_CALLSCAN) ||
841                                  (cli.mode & MODE_JAM   ) ))
842                {
843                        if ( time(NULL) > cli.last_hop + cli.hop_ch_time )
844                        {
845                                cli.channel++;
846
847                                if (cli.channel > cli.hop_end)
848                                        cli.channel = cli.hop_start;
849
850                                set_channel(cli.channel);
851                        }
852                }
853
854                if (cli.autorec)
855                {
856                        if ( (time (NULL) - cli.autorec_last_bfield
857                              > cli.autorec_timeout)
858                            &&
859                              (cli.mode != MODE_CALLSCAN)
860                           )
861                        {
862                                do_stop_keep_autorec();
863                                do_callscan();
864                                if (cli.pcap)
865                                {
866                                        pcap_dump_close(cli.pcap_d);
867                                        pcap_close(cli.pcap);
868                                        cli.pcap_d = NULL;
869                                        cli.pcap   = NULL;
870                                        cli.hop = 1;
871                                }
872                        }
873                }
874        }
875
876}
877
878int main(int argc, char ** argv)
879{
880        init();
881        /* make stdout unbuffered */
882        setvbuf(stdout,(char*)NULL,_IONBF,0);
883        printf("DECT command line interface\n");
884        printf("type \"help\" if you're lost\n");
885        mainloop();
886        return 0;
887}
Note: See TracBrowser for help on using the repository browser.