Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
François Revol
firmware
Commits
de1e0902
Commit
de1e0902
authored
Jul 18, 2020
by
schneider
Browse files
Merge branch 'schneider/covid-tracing' into 'master'
Show COVID-19 exposure notification statistics See merge request
card10/firmware!392
parents
c0a3ed9e
ae08d2f9
Changes
9
Hide whitespace changes
Inline
Side-by-side
epicardium/ble/ble_main.c
View file @
de1e0902
...
...
@@ -45,10 +45,15 @@
#include
"api/interrupt-sender.h"
#include
"modules/log.h"
#define SCAN_REPORTS_NUM 16
static
bool
active
;
static
uint8_t
advertising_mode
=
APP_MODE_NONE
;
static
uint8_t
advertising_mode_target
=
APP_MODE_NONE
;
static
enum
ble_event_type
ble_event
;
static
struct
epic_scan_report
scan_reports
[
SCAN_REPORTS_NUM
];
static
int
scan_reports_head
;
static
int
scan_reports_tail
;
/**************************************************************************************************
Macros
...
...
@@ -188,6 +193,15 @@ static const uint8_t bleAdvDataConn[] =
DM_FLAG_LE_BREDR_NOT_SUP
,
};
static
const
appMasterCfg_t
scannerMasterCfg
=
{
420
,
/*! The scan interval, in 0.625 ms units */
420
,
/*! The scan window, in 0.625 ms units */
0
,
/*! The scan duration in ms */
DM_DISC_MODE_NONE
,
/*! The GAP discovery mode */
DM_SCAN_TYPE_PASSIVE
/*!< The scan type (active or passive) */
};
/**************************************************************************************************
Client Characteristic Configuration Descriptors
...
...
@@ -472,15 +486,45 @@ static void bleSetup(bleMsg_t *pMsg)
active
=
true
;
/* TODO: Sadly, not advertising leads to a higher current consumption... */
epic_ble_set_
bondable
(
false
);
epic_ble_set_
mode
(
false
,
false
);
}
void
epic_ble_set_
bondabl
e
(
bool
bondable
)
void
epic_ble_set_
mod
e
(
bool
bondable
,
bool
scanner
)
{
if
(
!
active
)
{
return
;
}
if
(
scanner
&&
bondable
)
{
/* TODO: return error */
return
;
}
if
(
scanner
)
{
if
(
advertising_mode
!=
APP_MODE_NONE
)
{
advertising_mode_target
=
APP_MODE_NONE
;
advertising_mode
=
APP_MODE_NONE
;
AppAdvStop
();
}
dmConnId_t
connId
;
if
((
connId
=
AppConnIsOpen
())
!=
DM_CONN_ID_NONE
)
{
AppConnClose
(
connId
);
}
/* Normal scanning filters out duplicates. We don't
* want that for now... */
//AppScanStart(scannerMasterCfg.discMode, scannerMasterCfg.scanType, scannerMasterCfg.scanDuration);
DmScanSetInterval
(
HCI_SCAN_PHY_LE_1M_BIT
,
&
pAppMasterCfg
->
scanInterval
,
&
pAppMasterCfg
->
scanWindow
);
DmScanStart
(
HCI_SCAN_PHY_LE_1M_BIT
,
scannerMasterCfg
.
discMode
,
&
scannerMasterCfg
.
scanType
,
FALSE
,
scannerMasterCfg
.
scanDuration
,
0
);
return
;
}
else
{
AppScanStop
();
}
if
(
bondable
)
{
/* We need to stop advertising in between or the
* adv set will not be changed.
...
...
@@ -549,7 +593,10 @@ static void trigger_event(enum ble_event_type event)
{
bool
enabled
;
epic_interrupt_is_enabled
(
EPIC_INT_BLE
,
&
enabled
);
if
(
ble_event
&&
enabled
)
{
/* Print a warning if the app is missing events. Missing scan results
* is considered OK though, as they are queued and periodic. */
if
(
ble_event
&&
enabled
&&
ble_event
!=
BLE_EVENT_SCAN_REPORT
)
{
LOG_WARN
(
"ble"
,
"Application missed event %u"
,
ble_event
);
}
...
...
@@ -576,6 +623,48 @@ static void bleHandleNumericComparison(dmSecCnfIndEvt_t *pCnfInd)
trigger_event
(
BLE_EVENT_HANDLE_NUMERIC_COMPARISON
);
}
int
epic_ble_get_scan_report
(
struct
epic_scan_report
*
rpt
)
{
if
(
scan_reports_head
==
scan_reports_tail
)
{
return
-
ENOENT
;
}
int
new_tail
=
(
scan_reports_tail
+
1
)
%
SCAN_REPORTS_NUM
;
*
rpt
=
scan_reports
[
new_tail
];
scan_reports_tail
=
new_tail
;
return
0
;
}
static
void
scannerScanReport
(
dmEvt_t
*
pMsg
)
{
struct
epic_scan_report
*
scan_report
;
int
next_head
=
(
scan_reports_head
+
1
)
%
SCAN_REPORTS_NUM
;
if
(
next_head
==
scan_reports_tail
)
{
trigger_event
(
BLE_EVENT_SCAN_REPORT
);
return
;
}
scan_reports_head
=
next_head
;
scan_report
=
&
scan_reports
[
scan_reports_head
];
memset
(
scan_report
->
data
,
0
,
sizeof
(
scan_report
->
data
));
memccpy
(
scan_report
->
data
,
pMsg
->
scanReport
.
pData
,
pMsg
->
scanReport
.
len
,
sizeof
(
scan_report
->
data
));
scan_report
->
len
=
pMsg
->
scanReport
.
len
;
scan_report
->
rssi
=
pMsg
->
scanReport
.
rssi
;
scan_report
->
eventType
=
pMsg
->
scanReport
.
eventType
;
scan_report
->
addrType
=
pMsg
->
scanReport
.
addrType
;
memcpy
(
scan_report
->
addr
,
pMsg
->
scanReport
.
addr
,
BDA_ADDR_LEN
);
scan_report
->
directAddrType
=
pMsg
->
scanReport
.
directAddrType
;
memcpy
(
scan_report
->
directAddr
,
pMsg
->
scanReport
.
directAddr
,
BDA_ADDR_LEN
);
trigger_event
(
BLE_EVENT_SCAN_REPORT
);
if
((
scan_reports_head
+
1
)
%
SCAN_REPORTS_NUM
==
scan_reports_tail
)
{
LOG_WARN
(
"ble"
,
"Application missing scan results"
);
}
}
/*************************************************************************************************/
/*!
* \brief Process messages from the event handler.
...
...
@@ -610,10 +699,9 @@ static void bleProcMsg(bleMsg_t *pMsg)
case
DM_ADV_START_IND
:
LOG_INFO
(
"ble"
,
"Advertisement started %u %u"
,
advertising_mode
,
advertising_mode_target
);
if
(
advertising_mode
!=
advertising_mode_target
)
{
if
(
advertising_mode
!=
advertising_mode_target
||
advertising_mode_target
==
APP_MODE_NONE
)
{
AppAdvStop
();
}
break
;
case
DM_ADV_STOP_IND
:
...
...
@@ -719,6 +807,10 @@ static void bleProcMsg(bleMsg_t *pMsg)
bleHandleNumericComparison
(
&
pMsg
->
dm
.
cnfInd
);
break
;
case
DM_SCAN_REPORT_IND
:
scannerScanReport
((
dmEvt_t
*
)
pMsg
);
break
;
case
DM_HW_ERROR_IND
:
LOG_ERR
(
"ble"
,
"HW Error"
);
break
;
...
...
@@ -749,6 +841,7 @@ static void BleHandlerInit(void)
pAppSlaveCfg
=
(
appSlaveCfg_t
*
)
&
bleSlaveCfg
;
pAppSecCfg
=
(
appSecCfg_t
*
)
&
bleSecCfg
;
pAppUpdateCfg
=
(
appUpdateCfg_t
*
)
&
bleUpdateCfg
;
pAppMasterCfg
=
(
appMasterCfg_t
*
)
&
scannerMasterCfg
;
/* Initialize application framework */
AppSlaveInit
();
...
...
@@ -779,7 +872,7 @@ static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
if
(
pMsg
->
event
>=
DM_CBACK_START
&&
pMsg
->
event
<=
DM_CBACK_END
)
{
LOG_INFO
(
"ble"
,
"Ble got evt %d: %s"
,
pMsg
->
event
,
dm_events
[
pMsg
->
event
-
DM_CBACK_START
]);
if
(
pMsg
->
event
!=
DM_SCAN_REPORT_IND
)
LOG_INFO
(
"ble"
,
"Ble got evt %d: %s"
,
pMsg
->
event
,
dm_events
[
pMsg
->
event
-
DM_CBACK_START
]);
/* process advertising and connection-related messages */
AppSlaveProcDmMsg
((
dmEvt_t
*
)
pMsg
);
...
...
epicardium/ble/stack.c
View file @
de1e0902
...
...
@@ -130,11 +130,7 @@ void StackInit(void)
.
freeMemAvail
=
LL_MEMORY_FOOTPRINT
};
#ifdef DATS_APP_USE_LEGACY_API
memUsed
=
LlInitControllerExtInit
(
&
ll_init_cfg
);
#else
/* DATS_APP_USE_LEGACY_API */
memUsed
=
LlInitControllerExtInit
(
&
ll_init_cfg
);
#endif
/* DATS_APP_USE_LEGACY_API */
if
(
memUsed
!=
LL_MEMORY_FOOTPRINT
)
{
printf
(
"Controller memory mismatch 0x%x != 0x%x
\n
"
,
(
unsigned
int
)
memUsed
,
...
...
@@ -142,6 +138,11 @@ void StackInit(void)
}
#endif
SecInit
();
SecRandInit
();
SecAesInit
();
SecCmacInit
();
SecEccInit
();
/* card10:
* These calls register a queue for callbacks in the OS abstraction
...
...
@@ -153,14 +154,10 @@ void StackInit(void)
handlerId
=
WsfOsSetNextHandler
(
HciHandler
);
HciHandlerInit
(
handlerId
);
SecInit
();
SecAesInit
();
SecCmacInit
();
SecEccInit
();
handlerId
=
WsfOsSetNextHandler
(
DmHandler
);
DmDevVsInit
(
0
);
DmAdvInit
();
DmScanInit
();
DmConnInit
();
DmConnSlaveInit
();
DmSecInit
();
...
...
epicardium/epicardium.h
View file @
de1e0902
...
...
@@ -149,10 +149,11 @@ typedef _Bool bool;
#define API_CONFIG_GET_BOOLEAN 0x132
#define API_CONFIG_SET_STRING 0x133
#define API_BLE_GET_COMPARE_VALUE 0x140
#define API_BLE_COMPARE_RESPONSE 0x141
#define API_BLE_SET_BONDABLE 0x142
#define API_BLE_GET_EVENT 0x143
#define API_BLE_GET_COMPARE_VALUE 0x140
#define API_BLE_COMPARE_RESPONSE 0x141
#define API_BLE_SET_MODE 0x142
#define API_BLE_GET_EVENT 0x143
#define API_BLE_GET_SCAN_REPORT 0x144
/* clang-format on */
...
...
@@ -2036,7 +2037,7 @@ API(API_USB_CDCACM, int epic_usb_cdcacm(void));
/**
* Takes a gpio pin specified with the gpio module and transmits
* the led data. The format `GG:RR:BB` is expected.
* the led data. The format
`
`GG:RR:BB`
`
is expected.
*
* :param uint8_t pin: The gpio pin to be used for data.
* :param uint8_t * pixels: The buffer, in which the pixel data is stored.
...
...
@@ -2135,9 +2136,29 @@ enum ble_event_type {
BLE_EVENT_PAIRING_FAILED
=
2
,
/** A pairing procedure has successfully completed */
BLE_EVENT_PAIRING_COMPLETE
=
3
,
/** New scan data is available */
BLE_EVENT_SCAN_REPORT
=
4
,
};
/**
* Scan report data. Bases on ``hciLeAdvReportEvt_t`` from BLE stack.
*
* TODO: 64 bytes for data is an arbitrary number ATM */
struct
epic_scan_report
{
uint8_t
data
[
64
];
/*!< \brief advertising or scan response data. */
uint8_t
len
;
/*!< \brief length of advertising or scan response data. */
int8_t
rssi
;
/*!< \brief RSSI. */
uint8_t
eventType
;
/*!< \brief Advertising event type. */
uint8_t
addrType
;
/*!< \brief Address type. */
uint8_t
addr
[
6
];
/*!< \brief Device address. */
/* \brief direct fields */
uint8_t
directAddrType
;
/*!< \brief Direct advertising address type. */
uint8_t
directAddr
[
6
];
/*!< \brief Direct advertising address. */
};
/**
* **Interrupt Service Routine** for :c:data:`EPIC_INT_BLE`
*
...
...
@@ -2202,22 +2223,44 @@ API(API_BLE_GET_COMPARE_VALUE, uint32_t epic_ble_get_compare_value(void));
API
(
API_BLE_COMPARE_RESPONSE
,
void
epic_ble_compare_response
(
bool
confirmed
));
/**
* Allow or disallow new bondings to happen
* Set the desired mode of the BLE stack.
*
* There are three allowed modes:
*
* - Peripheral which is not bondable (bondable = ``false``, scanner = ``false``).
* - Peripheral which is bondable (bondable = ``true``, scanner = ``false``).
* - Observer which scans for advertisements (bondable = ``false``, scanner = ``true``).
*
* By default the card10 will not allow new bondings to be made. New
* bondings have to explicitly allowed by calling this function.
*
* While bon
a
dable the card10 will change its advertisements to
* While bondable the card10 will change its advertisements to
* indicate to scanning hosts that it is available for discovery.
*
* When scanning is active, :c:data:`BLE_EVENT_SCAN_REPORT` events will be sent
* and the scan reports can be fetched using :c:func:`epic_ble_get_scan_report`.
*
* When switching applications new bondings are automatically
* disallowed.
* disallowed
and scanning is stopped
.
*
* :param bool bondable: `true` if new bondings should be allowed.
* :param bool scanner: `true` if scanning should be turned on.
*
* .. versionadded:: 1.16
*/
API
(
API_BLE_SET_
BONDABL
E
,
void
epic_ble_set_
bondabl
e
(
bool
bondable
));
API
(
API_BLE_SET_
MOD
E
,
void
epic_ble_set_
mod
e
(
bool
bondable
,
bool
scanner
));
/**
* Retrieve a scan report from the queue of scan reports.
*
* :param struct epic_scan_report* rpt: Pointer where the report will be stored.
*
* :return: `0` on success or a negative value if an error occured. Possible
* errors:
*
* - ``-ENOENT``: No scan report available
*
*/
API
(
API_BLE_GET_SCAN_REPORT
,
int
epic_ble_get_scan_report
(
struct
epic_scan_report
*
rpt
));
#endif
/* _EPICARDIUM_H */
epicardium/modules/hardware.c
View file @
de1e0902
...
...
@@ -292,7 +292,7 @@ int hardware_reset(void)
/*
* BLE
*/
epic_ble_set_
bondable
(
false
);
epic_ble_set_
mode
(
false
,
false
);
return
0
;
}
lib/sdk/Libraries/BTLE/meson.build
View file @
de1e0902
...
...
@@ -421,6 +421,7 @@ ble_compileargs = [
'-DINIT_BROADCASTER',
'-DINIT_PERIPHERAL',
'-DINIT_ENCRYPTED',
'-DINIT_OBSERVER',
]
if get_option('ble_trace')
...
...
preload/apps/exnostat/__init__.py
0 → 100644
View file @
de1e0902
import
interrupt
import
sys_ble
import
time
import
vibra
import
display
import
color
import
buttons
import
leds
import
config
DM_ADV_TYPE_FLAGS
=
0x01
DM_ADV_TYPE_16_UUID
=
0x03
DM_ADV_TYPE_SERVICE_DATA
=
0x16
UUID
=
b
"
\x6f\xfd
"
TIMEOUT
=
100
MODE_OFF
=
0
MODE_ON_NEW_MAC
=
1
MODE_ON_RX
=
2
MODE_BOTH
=
3
seen
=
{}
vib_mode
=
MODE_BOTH
led_mode
=
MODE_BOTH
def
parse_advertisement_data
(
data
):
ads
=
{}
l
=
len
(
data
)
p
=
0
while
p
<
l
:
ad_len
=
data
[
p
]
p
+=
1
if
ad_len
>
0
:
ad_type
=
data
[
p
]
ad_data
=
b
""
p
+=
1
if
ad_len
>
1
:
ad_data
=
data
[
p
:
p
+
ad_len
-
1
]
p
+=
ad_len
-
1
ads
[
ad_type
]
=
ad_data
return
ads
def
bytes2hex
(
bin
,
sep
=
""
):
return
sep
.
join
([
"%02x"
%
x
for
x
in
bin
])
def
process_covid_data
(
mac
,
service_data
,
rssi
,
flags
):
global
vib_mode
if
vib_mode
in
[
MODE_ON_RX
,
MODE_BOTH
]:
vibra
.
vibrate
(
10
)
if
vib_mode
in
[
MODE_ON_NEW_MAC
,
MODE_BOTH
]
and
mac
not
in
seen
:
vibra
.
vibrate
(
100
)
if
led_mode
in
[
MODE_ON_RX
,
MODE_BOTH
]:
leds
.
flash_rocket
(
0
,
31
,
20
)
if
led_mode
in
[
MODE_ON_NEW_MAC
,
MODE_BOTH
]
and
mac
not
in
seen
:
leds
.
flash_rocket
(
1
,
31
,
200
)
print
(
bytes2hex
(
mac
,
":"
),
rssi
,
bytes2hex
(
service_data
),
flags
)
# try to produce a small int
last_rx_time
=
time
.
time
()
-
t0
seen
[
mac
]
=
[
int
(
last_rx_time
),
flags
]
def
prune
():
global
seen
seen_pruned
=
{}
now
=
time
.
time
()
-
t0
for
mac
in
seen
:
if
seen
[
mac
][
0
]
+
TIMEOUT
>
now
:
seen_pruned
[
mac
]
=
seen
[
mac
]
seen
=
seen_pruned
def
process_scan_report
(
scan_report
):
ads
=
parse_advertisement_data
(
scan_report
[
0
])
mac
=
scan_report
[
4
]
mac
=
bytes
([
mac
[
5
],
mac
[
4
],
mac
[
3
],
mac
[
2
],
mac
[
1
],
mac
[
0
]])
rssi
=
scan_report
[
1
]
# print(bytes2hex(mac, ':'), rssi, bytes2hex(scan_report[0]), ads)
# According to spec there is no other service announced and the
# service is always listed in the complete list of 16 bit services
if
DM_ADV_TYPE_16_UUID
in
ads
:
if
ads
[
DM_ADV_TYPE_16_UUID
]
==
UUID
:
if
DM_ADV_TYPE_SERVICE_DATA
in
ads
:
flags
=
None
if
DM_ADV_TYPE_FLAGS
in
ads
:
flags
=
ads
[
DM_ADV_TYPE_FLAGS
]
# service data contains another copy of the service UUID
process_covid_data
(
mac
,
ads
[
DM_ADV_TYPE_SERVICE_DATA
][
2
:],
rssi
,
flags
)
def
ble_callback
(
_
):
event
=
sys_ble
.
get_event
()
if
event
==
sys_ble
.
EVENT_SCAN_REPORT
:
while
True
:
scan_report
=
sys_ble
.
get_scan_report
()
if
scan_report
==
None
:
break
process_scan_report
(
scan_report
)
prune
()
def
show_stats
():
seen_google
=
0
seen_apple
=
0
t
=
time
.
time
()
-
t0
t_min
=
t
# Make a copy as `seen` could change in between
# and we're not locking it
seen_copy
=
seen
.
copy
()
for
mac
in
seen_copy
:
info
=
seen_copy
[
mac
]
if
info
[
1
]:
seen_apple
+=
1
else
:
seen_google
+=
1
if
info
[
0
]
<
t_min
:
t_min
=
info
[
0
]
seen_total
=
seen_google
+
seen_apple
window
=
t
-
t_min
if
len
(
seen_copy
)
>
0
else
min
(
TIMEOUT
,
t
-
last_rx_time
)
disp
.
clear
()
disp
.
print
(
"Last %u s:"
%
window
,
posy
=
0
,
fg
=
color
.
WHITE
)
disp
.
print
(
"Google: %d"
%
seen_google
,
posy
=
20
,
fg
=
color
.
GREEN
)
disp
.
print
(
"Apple: %d"
%
seen_apple
,
posy
=
40
,
fg
=
color
.
BLUE
)
disp
.
print
(
"Total: %d"
%
seen_total
,
posy
=
60
,
fg
=
color
.
WHITE
)
disp
.
update
()
last_rx_time
=
0
disp
=
display
.
open
()
v_old
=
0
pause
=
1
interrupt
.
set_callback
(
interrupt
.
BLE
,
ble_callback
)
interrupt
.
enable_callback
(
interrupt
.
BLE
)
try
:
vib_mode
=
int
(
config
.
get_string
(
"exno_vib_mode"
))
except
:
pass
try
:
led_mode
=
int
(
config
.
get_string
(
"exno_led_mode"
))
except
:
pass
disp
.
clear
()
disp
.
print
(
" Exp Notif"
,
posy
=
0
,
fg
=
color
.
WHITE
)
disp
.
print
(
" Counter"
,
posy
=
20
,
fg
=
color
.
WHITE
)
disp
.
print
(
"Vib Mode ->"
,
posy
=
40
,
fg
=
color
.
GREEN
)
disp
.
print
(
"<- LED Mode"
,
posy
=
60
,
fg
=
color
.
BLUE
)
disp
.
update
()
time
.
sleep
(
3
)
t0
=
time
.
time
()
sys_ble
.
scan_start
()
while
True
:
v_new
=
buttons
.
read
()
v
=
~
v_old
&
v_new
v_old
=
v_new
if
v
&
buttons
.
TOP_RIGHT
:
disp
.
clear
()
disp
.
print
(
"Vib Mode:"
,
posy
=
0
,
fg
=
color
.
WHITE
)
if
vib_mode
==
MODE_OFF
:
vib_mode
=
MODE_ON_NEW_MAC
disp
.
print
(
"New MAC"
,
posy
=
40
,
fg
=
color
.
YELLOW
)
elif
vib_mode
==
MODE_ON_NEW_MAC
:
vib_mode
=
MODE_ON_RX
disp
.
print
(
"Each RX"
,
posy
=
40
,
fg
=
color
.
BLUE
)
elif
vib_mode
==
MODE_ON_RX
:
vib_mode
=
MODE_BOTH
disp
.
print
(
"MAC"
,
posy
=
40
,
fg
=
color
.
YELLOW
)
disp
.
print
(
"&"
,
posy
=
40
,
posx
=
14
*
4
,
fg
=
color
.
WHITE
)
disp
.
print
(
"RX"
,
posy
=
40
,
posx
=
14
*
6
,
fg
=
color
.
BLUE
)
elif
vib_mode
==
MODE_BOTH
:
vib_mode
=
MODE_OFF
disp
.
print
(
"Vib off"
,
posy
=
40
,
fg
=
color
.
WHITE
)
disp
.
update
()
config
.
set_string
(
"exno_vib_mode"
,
str
(
vib_mode
))
pause
=
20
if
v
&
buttons
.
BOTTOM_LEFT
:
disp
.
clear
()
disp
.
print
(
"LED Mode:"
,
posy
=
0
,
fg
=
color
.
WHITE
)
if
led_mode
==
MODE_OFF
:
led_mode
=
MODE_ON_NEW_MAC
disp
.
print
(
"New MAC"
,
posy
=
40
,
fg
=
color
.
YELLOW
)
elif
led_mode
==
MODE_ON_NEW_MAC
:
led_mode
=
MODE_ON_RX
disp
.
print
(
"Each RX"
,
posy
=
40
,
fg
=
color
.
BLUE
)
elif
led_mode
==
MODE_ON_RX
:
led_mode
=
MODE_BOTH
disp
.
print
(
"MAC"
,
posy
=
40
,
fg
=
color
.
YELLOW
)
disp
.
print
(
"&"
,
posy
=
40
,
posx
=
14
*
4
,
fg
=
color
.
WHITE
)
disp
.
print
(
"RX"
,
posy
=
40
,
posx
=
14
*
6
,
fg
=
color
.
BLUE
)
elif
led_mode
==
MODE_BOTH
:
led_mode
=
MODE_OFF
disp
.
print
(
"LED off"
,
posy
=
40
,
fg
=
color
.
WHITE
)
disp
.
update
()
config
.
set_string
(
"exno_led_mode"
,
str
(
led_mode
))
pause
=
20
pause
-=
1
if
pause
==
0
:
show_stats
()
pause
=
10
time
.
sleep
(
0.1
)
preload/apps/exnostat/metadata.json
0 → 100644
View file @
de1e0902
{
"author"
:
"schneider"
,
"name"
:
"Exposure Notification Stats"
,
"description"
:
"Count Exposure Notifications received via BLE"
,
"category"
:
"Hardware"
,
"revision"
:
1
,
"source"
:
"preload"
}
pycardium/modules/qstrdefs.h
View file @
de1e0902
...
...
@@ -199,11 +199,14 @@ Q(get_string)
Q
(
BLE
)
Q
(
ble
)
Q
(
get_compare_value
)
Q
(
get_scan_report
)
Q
(
confirm_compare_value
)
Q
(
set_bondable
)
Q
(
scan_start
)
Q
(
get_event
)
Q
(
EVENT_NONE
)
Q
(
EVENT_HANDLE_NUMERIC_COMPARISON
)
Q
(
EVENT_PAIRING_COMPLETE
)
Q
(
EVENT_PAIRING_FAILED
)
Q
(
EVENT_SCAN_REPORT
)
pycardium/modules/sys_ble.c
View file @
de1e0902
...
...
@@ -24,6 +24,29 @@ static MP_DEFINE_CONST_FUN_OBJ_0(
ble_get_compare_value_obj
,
mp_ble_get_compare_value
);
static
mp_obj_t
mp_ble_get_scan_report
(
void
)
{
struct
epic_scan_report
scan_report
;
int
ret
=
epic_ble_get_scan_report
(
&
scan_report
);
if
(
ret
<
0
)
{
return
mp_const_none
;
}
mp_obj_t
data
=
mp_obj_new_bytes
(
scan_report
.
data
,
scan_report
.
len
);
mp_obj_t
rssi
=
MP_OBJ_NEW_SMALL_INT
(
scan_report
.
rssi
);
mp_obj_t
eventType
=
MP_OBJ_NEW_SMALL_INT
(
scan_report
.
eventType
);
mp_obj_t
addrType
=
MP_OBJ_NEW_SMALL_INT
(
scan_report
.
addrType
);
mp_obj_t
addr
=
mp_obj_new_bytes
(
scan_report
.
addr
,
6
);
mp_obj_t
values_list
[]
=
{
data
,
rssi
,
eventType
,
addrType
,
addr
};
return
mp_obj_new_tuple
(
5
,
values_list
);
}
static
MP_DEFINE_CONST_FUN_OBJ_0
(
ble_get_scan_report_obj
,
mp_ble_get_scan_report
);
static
mp_obj_t
mp_ble_get_event
(
void
)
{
return
mp_obj_new_int
(
epic_ble_get_event
());
...
...
@@ -33,20 +56,30 @@ static MP_DEFINE_CONST_FUN_OBJ_0(ble_get_event_obj, mp_ble_get_event);
static
mp_obj_t
mp_ble_set_bondable
(
mp_obj_t
bondable_ob