Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
firmware
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
François Revol
firmware
Commits
de1e0902
Commit
de1e0902
authored
Jul 18, 2020
by
schneider
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'schneider/covid-tracing' into 'master'
Show COVID-19 exposure notification statistics See merge request
!392
parents
c0a3ed9e
ae08d2f9
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
427 additions
and
26 deletions
+427
-26
epicardium/ble/ble_main.c
epicardium/ble/ble_main.c
+99
-6
epicardium/ble/stack.c
epicardium/ble/stack.c
+6
-9
epicardium/epicardium.h
epicardium/epicardium.h
+52
-9
epicardium/modules/hardware.c
epicardium/modules/hardware.c
+1
-1
lib/sdk/Libraries/BTLE/meson.build
lib/sdk/Libraries/BTLE/meson.build
+1
-0
preload/apps/exnostat/__init__.py
preload/apps/exnostat/__init__.py
+228
-0
preload/apps/exnostat/metadata.json
preload/apps/exnostat/metadata.json
+1
-0
pycardium/modules/qstrdefs.h
pycardium/modules/qstrdefs.h
+3
-0
pycardium/modules/sys_ble.c
pycardium/modules/sys_ble.c
+36
-1
No files found.
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_
bondable
(
bool
bondable
)
void
epic_ble_set_
mode
(
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_
BONDABLE
,
void
epic_ble_set_bondable
(
bool
bondable
));
API
(
API_BLE_SET_
MODE
,
void
epic_ble_set_mode
(
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_obj
)
{
bool
bondable
=
mp_obj_is_true
(
bondable_obj
);
epic_ble_set_
bondable
(
bondabl
e
);
epic_ble_set_
mode
(
bondable
,
fals
e
);
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_1
(
ble_set_bondable_obj
,
mp_ble_set_bondable
);
static
mp_obj_t
mp_ble_scan_start
()
{
epic_ble_set_mode
(
false
,
true
);
return
mp_const_none
;
}
static
MP_DEFINE_CONST_FUN_OBJ_0
(
ble_scan_start_obj
,
mp_ble_scan_start
);
static
const
mp_rom_map_elem_t
ble_module_globals_table
[]
=
{
{
MP_ROM_QSTR
(
MP_QSTR___name__
),
MP_ROM_QSTR
(
MP_QSTR_sys_ble
)
},
{
MP_ROM_QSTR
(
MP_QSTR_confirm_compare_value
),
MP_ROM_PTR
(
&
ble_confirm_compare_value_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_get_compare_value
),
MP_ROM_PTR
(
&
ble_get_compare_value_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_get_scan_report
),
MP_ROM_PTR
(
&
ble_get_scan_report_obj
)
},