1 #include <linux/input.h>
13 #include "tapi-port.h"
14 #include "dialdetector.h"
16 static const struct itimerspec dialdetector_timeout
= {
20 static void dialdetector_note_digit(struct dialdetector
*d
, unsigned char digit
)
22 printf("note digit: %d\n", d
->num_digits
);
23 d
->digits
[d
->num_digits
] = digit
;
27 static void dialdetector_reset(struct dialdetector
*d
)
29 event_unregister(d
->timer_fd
);
31 d
->state
= DIALDETECTOR_IDLE
;
34 static bool dialdetector_timeout_event(int events
, void *data
)
37 struct dialdetector
*dialdetector
= data
;
40 for (i
= 0; i
< dialdetector
->num_digits
; ++i
) {
41 num
[i
] = '0' + dialdetector
->digits
[i
];
45 printf("Dialing: %s\n", num
);
46 dialdetector
->dial_callback(dialdetector
->port
, dialdetector
->num_digits
,
47 dialdetector
->digits
);
49 dialdetector_reset(dialdetector
);
54 static void dialdetector_port_event(struct tapi_port
*port
,
55 struct tapi_event
*event
, void *data
)
57 struct dialdetector
*d
= data
;
59 printf("port event: %d %d\n", d
->state
, event
->hook
.on
);
62 case DIALDETECTOR_IDLE
:
63 if (event
->type
== TAPI_EVENT_TYPE_HOOK
&& event
->hook
.on
== false) {
64 d
->state
= DIALDETECTOR_WAIT_FOR_NUMBER
;
65 event_register(d
->timer_fd
, EPOLLIN
, &d
->timeout_cb
);
66 timerfd_settime(d
->timer_fd
, 0, &dialdetector_timeout
, NULL
);
69 case DIALDETECTOR_WAIT_FOR_NUMBER
:
70 case DIALDETECTOR_WAIT_FOR_NUMBER_TIMEOUT
:
71 switch (event
->type
) {
72 case TAPI_EVENT_TYPE_HOOK
:
73 if (event
->hook
.on
== true)
74 dialdetector_reset(d
);
76 case TAPI_EVENT_TYPE_DTMF
:
77 if (d
->state
== DIALDETECTOR_WAIT_FOR_NUMBER
)
78 event_register(d
->timer_fd
, EPOLLIN
, &d
->timeout_cb
);
79 timerfd_settime(d
->timer_fd
, 0, &dialdetector_timeout
, NULL
);
80 d
->state
= DIALDETECTOR_WAIT_FOR_NUMBER_TIMEOUT
;
81 dialdetector_note_digit(d
, event
->dtmf
.code
);
89 struct dialdetector
*dialdetector_alloc(struct tapi_port
*port
)
91 struct dialdetector
*dialdetector
;
92 dialdetector
= malloc(sizeof(*dialdetector
));
94 dialdetector
->timer_fd
= timerfd_create(CLOCK_MONOTONIC
, 0);
95 dialdetector
->port
= port
;
96 dialdetector
->num_digits
= 0;
97 dialdetector
->state
= DIALDETECTOR_IDLE
;
99 dialdetector
->timeout_cb
.callback
= dialdetector_timeout_event
;
100 dialdetector
->timeout_cb
.data
= dialdetector
;
102 dialdetector
->port_listener
.callback
= dialdetector_port_event
;
103 dialdetector
->port_listener
.data
= dialdetector
;
105 tapi_port_register_event(port
, &dialdetector
->port_listener
);