• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

canokeys / canokey-core / 9832823186

08 Jul 2024 03:01AM UTC coverage: 79.025%. Remained the same
9832823186

push

github

web-flow
Merge pull request #92 from canokeys/fix-led-state

Fix initial LED state (bug introduced in 4fb369f4)

0 of 1 new or added line in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

6503 of 8229 relevant lines covered (79.03%)

555.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.66
/src/device.c
1
// SPDX-License-Identifier: Apache-2.0
2
#include "common.h"
3
#include <admin.h>
4
#include <ccid.h>
5
#include <ctaphid.h>
6
#include <device.h>
7
#include <kbdhid.h>
8
#include <webusb.h>
9

10
volatile static uint8_t touch_result;
11
static uint8_t has_rf;
12
static uint32_t last_blink, blink_timeout, blink_interval;
13
static enum { ON, OFF } led_status;
14
typedef enum { WAIT_NONE = 1, WAIT_CCID, WAIT_CTAPHID, WAIT_DEEP, WAIT_DEEP_TOUCHED, WAIT_DEEP_CANCEL } wait_status_t;
15
volatile static wait_status_t wait_status = WAIT_NONE; // WAIT_NONE is not 0, hence inited
16

17
uint8_t device_is_blinking(void) { return blink_timeout != 0; }
819✔
18

19
void device_loop(uint8_t has_touch) {
20
  CCID_Loop();
×
21
  CTAPHID_Loop(0);
×
22
  WebUSB_Loop();
×
23
  KBDHID_Loop();
×
24
}
×
25

26
bool device_allow_kbd_touch(void) {
27
  uint32_t now = device_get_tick();
×
28
  if (!device_is_blinking() &&      // applets are not waiting for touch
×
29
      now > 2000   &&               // ignore touch for the first 2 seconds
×
30
      now - 1000 > last_blink &&
×
31
      get_touch_result() != TOUCH_NO
×
32
  ) {
33
    DBG_MSG("now=%lu last_blink=%lu\n", now, last_blink);
×
34
    return true;
×
35
  }
36
  return false;
×
37
}
38

39
uint8_t get_touch_result(void) {
40
#ifdef TEST // emulate user interaction in test mode
41
  testmode_emulate_user_presence();
395✔
42
#endif
43
  return touch_result;
395✔
44
}
45

46
void set_touch_result(uint8_t result) { touch_result = result; }
790✔
47

48
uint8_t wait_for_user_presence(uint8_t entry) {
49
  start_blinking(0);
359✔
50
  uint32_t start = device_get_tick();
359✔
51
  uint32_t last = start;
359✔
52
  DBG_MSG("start %u\n", start);
359✔
53

54
  wait_status_t shallow = wait_status;
359✔
55
  if (wait_status == WAIT_NONE) {
359✔
56
    switch (entry) {
359✔
57
    case WAIT_ENTRY_CCID:
4✔
58
      wait_status = WAIT_CCID;
4✔
59
      break;
4✔
60
    case WAIT_ENTRY_CTAPHID:
355✔
61
      wait_status = WAIT_CTAPHID;
355✔
62
      break;
355✔
63
    }
64
  } else
65
    wait_status = WAIT_DEEP;
×
66
  while (get_touch_result() == TOUCH_NO) {
359✔
67
    if (wait_status == WAIT_DEEP_TOUCHED || wait_status == WAIT_DEEP_CANCEL) break;
×
68
    if (wait_status == WAIT_CTAPHID) CCID_Loop();
×
69
    if (CTAPHID_Loop(wait_status != WAIT_CCID) == LOOP_CANCEL) {
×
70
      DBG_MSG("Cancelled by host\n");
×
71
      if (wait_status != WAIT_DEEP) {
×
72
        stop_blinking();
×
73
        wait_status = WAIT_NONE; // namely shallow
×
74
      } else
75
        wait_status = WAIT_DEEP_CANCEL;
×
76
      return USER_PRESENCE_CANCEL;
×
77
    }
78
    uint32_t now = device_get_tick();
×
79
    if (now - start >= 30000) {
×
80
      DBG_MSG("timeout at %u\n", now);
×
81
      if (wait_status != WAIT_DEEP) stop_blinking();
×
82
      wait_status = shallow;
×
83
      return USER_PRESENCE_TIMEOUT;
×
84
    }
85
    if (now - last >= 100) {
×
86
      last = now;
×
87
      if (wait_status != WAIT_CCID) CTAPHID_SendKeepAlive(KEEPALIVE_STATUS_UPNEEDED);
×
88
    }
89
  }
90
  set_touch_result(TOUCH_NO);
359✔
91
  if (wait_status != WAIT_DEEP) stop_blinking();
359✔
92
  if (wait_status == WAIT_DEEP)
359✔
93
    wait_status = WAIT_DEEP_TOUCHED;
×
94
  else if (wait_status == WAIT_DEEP_CANCEL) {
359✔
95
    wait_status = WAIT_NONE;
×
96
    return USER_PRESENCE_TIMEOUT;
×
97
  } else
98
    wait_status = WAIT_NONE;
359✔
99
  return USER_PRESENCE_OK;
359✔
100
}
101

102
int send_keepalive_during_processing(uint8_t entry) {
103
  if (entry == WAIT_ENTRY_CTAPHID) CTAPHID_SendKeepAlive(KEEPALIVE_STATUS_PROCESSING);
546✔
104
  DBG_MSG("KEEPALIVE\n");
546✔
105
  return 0;
546✔
106
}
107

108
__attribute__((weak)) int strong_user_presence_test(void) {
109
  for (int i = 0; i < 5; i++) {
×
110
    const uint8_t wait_sec = 2;
×
111
    start_blinking_interval(wait_sec, (i & 1) ? 200 : 50);
×
112
    uint32_t now, begin = device_get_tick();
×
113
    bool user_presence = false;
×
114
    do {
115
      if (get_touch_result() == TOUCH_SHORT) {
×
116
        user_presence = true;
×
117
        set_touch_result(TOUCH_NO);
×
118
        stop_blinking();
×
119
        // wait for some time before next user-precense test
120
        begin = device_get_tick();
×
121
      }
122
      now = device_get_tick();
×
123
    } while (now - begin < 1000 * wait_sec);
×
124
    if (!user_presence) {
×
125
      return -1;
×
126
    }
127
  }
128
  return 0;
×
129
}
130

131
void set_nfc_state(uint8_t val) { has_rf = val; }
1,640✔
132

133
uint8_t is_nfc(void) {
134
#ifdef TEST // read NFC emulation config from a file
135
  testmode_get_is_nfc_mode();
1,643✔
136
#endif
137
  return has_rf;
1,643✔
138
}
139

140
static void toggle_led(void) {
424✔
141
  if (led_status == ON) {
424✔
142
    led_off();
422✔
143
    led_status = OFF;
422✔
144
  } else {
145
    led_on();
2✔
146
    led_status = ON;
2✔
147
  }
148
}
424✔
149

150
void device_update_led(void) {
151
  uint32_t now = device_get_tick();
×
152
  if (now > blink_timeout) stop_blinking();
×
NEW
153
  if (device_is_blinking() && now >= last_blink && now - last_blink >= blink_interval) {
×
154
    last_blink = now;
×
155
    toggle_led();
×
156
  }
UNCOV
157
}
×
158

159
void start_blinking_interval(uint8_t sec, uint32_t interval) {
160
  if (device_is_blinking()) return;
424✔
161
  last_blink = device_get_tick();
424✔
162
  blink_interval = interval;
424✔
163
  if (sec == 0) {
424✔
164
    blink_timeout = UINT32_MAX;
388✔
165
  } else {
166
    blink_timeout = last_blink + sec * 1000;
36✔
167
  }
168
  toggle_led();
424✔
169
}
170

171
void stop_blinking(void) {
172
  blink_timeout = 0;
2,175✔
173
  if (cfg_is_led_normally_on()) {
2,175✔
174
    led_on();
2,163✔
175
    led_status = ON;
2,163✔
176
  } else {
177
    led_off();
12✔
178
    led_status = OFF;
12✔
179
  }
180
}
2,175✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc