forked from rene0/dcf77pi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mainloop.c
161 lines (142 loc) · 4.15 KB
/
mainloop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2014-2019 René Ladan
// SPDX-License-Identifier: BSD-2-Clause
#include "mainloop.h"
#include "bits1to14.h"
#include "decode_alarm.h"
#include "decode_time.h"
#include "input.h"
#include "setclock.h"
#include <string.h>
#include <time.h>
static void
check_handle_new_minute(struct GB_result bit, struct ML_result *mlr,
int bitpos, struct tm *curtime, int minlen, bool was_toolong,
unsigned *init_min, void (*display_minute)(int),
void (*display_thirdparty_buffer)(const unsigned[]),
void (*display_alarm)(struct alm), void (*display_unknown)(void),
void (*display_weather)(void),
void (*display_time)(struct DT_result, struct tm),
struct ML_result (*process_setclock_result)(struct ML_result, int))
{
bool have_result = false;
if ((bit.marker == emark_minute || bit.marker == emark_late) &&
!was_toolong) {
struct DT_result dt;
display_minute(minlen);
dt = decode_time(*init_min, minlen, get_acc_minlen(),
get_buffer(), curtime);
if (curtime->tm_min % 3 == 0 && *init_min == 0) {
const unsigned *tpbuf;
tpbuf = get_thirdparty_buffer();
display_thirdparty_buffer(tpbuf);
switch (get_thirdparty_type()) {
case eTP_alarm:
{
struct alm civwarn;
decode_alarm(tpbuf, &civwarn);
display_alarm(civwarn);
break;
}
case eTP_unknown:
display_unknown();
break;
case eTP_weather:
display_weather();
break;
}
}
display_time(dt, *curtime);
if (mlr->settime) {
have_result = true;
if (setclock_ok(*init_min, dt, bit)) {
mlr->settime_result = setclock(*curtime);
} else {
mlr->settime_result = esc_unsafe;
}
}
if (bit.marker == emark_minute || bit.marker == emark_late) {
reset_acc_minlen();
}
if (*init_min > 0) {
(*init_min)--;
}
}
if (have_result && process_setclock_result != NULL) {
*mlr = process_setclock_result(*mlr, bitpos);
}
}
void
mainloop(char *logfilename, struct GB_result (*get_bit)(void),
void (*display_bit)(struct GB_result, int),
void (*display_long_minute)(void), void (*display_minute)(int),
void (*display_new_second)(void), void (*display_alarm)(struct alm),
void (*display_unknown)(void), void (*display_weather)(void),
void (*display_time)(struct DT_result, struct tm),
void (*display_thirdparty_buffer)(const unsigned[]),
struct ML_result (*process_setclock_result)(struct ML_result, int),
struct ML_result (*process_input)(struct ML_result, int),
struct ML_result (*post_process_input)(struct ML_result, int))
{
int minlen = 0;
int bitpos = 0;
unsigned init_min = 2;
struct tm curtime;
struct ML_result mlr;
bool was_toolong = false;
(void)memset(&curtime, 0, sizeof(curtime));
(void)memset(&mlr, 0, sizeof(mlr));
mlr.logfilename = logfilename;
for (;;) {
struct GB_result bit;
bit = get_bit();
if (process_input != NULL) {
mlr = process_input(mlr, bitpos);
if (bit.done || mlr.quit) {
break;
}
}
bitpos = get_bitpos();
if (post_process_input != NULL) {
mlr = post_process_input(mlr, bitpos);
}
if (!bit.skip && !mlr.quit) {
display_bit(bit, bitpos);
}
if (init_min < 2) {
fill_thirdparty_buffer(curtime.tm_min, bitpos, bit);
}
bit = next_bit();
if (minlen == -1) {
check_handle_new_minute(bit, &mlr, bitpos, &curtime,
minlen, was_toolong, &init_min, display_minute,
display_thirdparty_buffer, display_alarm,
display_unknown, display_weather, display_time,
process_setclock_result);
was_toolong = true;
}
if (bit.marker == emark_minute) {
minlen = bitpos + 1;
/* handle the missing bit due to the minute marker */
} else if (bit.marker == emark_toolong ||
bit.marker == emark_late) {
minlen = -1;
/*
* leave acc_minlen alone, any minute marker already
* processed
*/
display_long_minute();
}
if (display_new_second != NULL) {
display_new_second();
}
check_handle_new_minute(bit, &mlr, bitpos, &curtime, minlen,
was_toolong, &init_min, display_minute,
display_thirdparty_buffer, display_alarm, display_unknown,
display_weather, display_time, process_setclock_result);
was_toolong = false;
if (bit.done || mlr.quit) {
break;
}
}
cleanup();
}