Commit 56b73d41 authored by Rahix's avatar Rahix
Browse files

Merge 'Show name of device which is connected / is trying to pair'

See merge request card10/firmware!407
parents bb104bd2 1308ae25
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "att_api.h" #include "att_api.h"
#include "dm_api.h" #include "dm_api.h"
#include "gatt/gatt_api.h" #include "gatt/gatt_api.h"
#include "gap/gap_api.h" #include "profiles/gap_api.h"
#include "tipc/tipc_api.h" #include "tipc/tipc_api.h"
#include "modules/log.h" #include "modules/log.h"
...@@ -73,6 +73,8 @@ static const attcDiscCfg_t bleDiscCfgList[] = ...@@ -73,6 +73,8 @@ static const attcDiscCfg_t bleDiscCfgList[] =
/* Write: GATT service changed ccc descriptor */ /* Write: GATT service changed ccc descriptor */
{bleGattScCccVal, sizeof(bleGattScCccVal), (GATT_SC_CCC_HDL_IDX + BLE_DISC_GATT_START)}, {bleGattScCccVal, sizeof(bleGattScCccVal), (GATT_SC_CCC_HDL_IDX + BLE_DISC_GATT_START)},
{NULL, 0, (GAP_DN_HDL_IDX + BLE_DISC_GAP_START)},
/* Read: GAP central address resolution attribute */ /* Read: GAP central address resolution attribute */
{NULL, 0, (GAP_CAR_HDL_IDX + BLE_DISC_GAP_START)}, {NULL, 0, (GAP_CAR_HDL_IDX + BLE_DISC_GAP_START)},
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "bas/bas_api.h" #include "bas/bas_api.h"
#include "hrps/hrps_api.h" #include "hrps/hrps_api.h"
#include "rscp/rscp_api.h" #include "rscp/rscp_api.h"
#include "profiles/gap_api.h"
#include "cccd.h" #include "cccd.h"
#include "ble_api.h" #include "ble_api.h"
...@@ -462,6 +463,7 @@ static void bleClose(bleMsg_t *pMsg) ...@@ -462,6 +463,7 @@ static void bleClose(bleMsg_t *pMsg)
{ {
/* stop battery measurement */ /* stop battery measurement */
BasMeasBattStop((dmConnId_t) pMsg->hdr.param); BasMeasBattStop((dmConnId_t) pMsg->hdr.param);
GapClearDeviceName();
} }
/*************************************************************************************************/ /*************************************************************************************************/
...@@ -593,6 +595,15 @@ uint32_t epic_ble_get_compare_value(void) ...@@ -593,6 +595,15 @@ uint32_t epic_ble_get_compare_value(void)
return pair_confirm_value; return pair_confirm_value;
} }
int epic_ble_get_peer_device_name(char *buf, size_t buf_size)
{
if (AppConnIsOpen() != DM_CONN_ID_NONE) {
return GapGetDeviceName(buf, buf_size);
} else {
return -ENOENT;
}
}
int epic_ble_get_last_pairing_name(char *buf, size_t buf_size) int epic_ble_get_last_pairing_name(char *buf, size_t buf_size)
{ {
if(last_pairing == NULL) { if(last_pairing == NULL) {
......
...@@ -4,6 +4,7 @@ ble_sources = files( ...@@ -4,6 +4,7 @@ ble_sources = files(
'ble_main.c', 'ble_main.c',
'ble_attc.c', 'ble_attc.c',
'profiles/tipc_main.c', 'profiles/tipc_main.c',
'profiles/gap_main.c',
'svc_dis.c', 'svc_dis.c',
'svc_core.c', 'svc_core.c',
'bondings.c', 'bondings.c',
......
/*************************************************************************************************/
/*!
* \file
*
* \brief GAP profile.
*
* Copyright (c) 2015-2018 Arm Ltd. All Rights Reserved.
* Arm Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact Arm Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#ifndef GAP_API_H
#define GAP_API_H
#include "att_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/*! \addtogroup GAP_PROFILE
* \{ */
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! \brief Enumeration of handle indexes of characteristics to be discovered */
enum
{
GAP_DN_HDL_IDX,
GAP_CAR_HDL_IDX, /*!< \brief Central Address Resolution */
GAP_RPAO_HDL_IDX, /*!< \brief Resolvable Private Address Only */
GAP_HDL_LIST_LEN /*!< \brief Handle list length */
};
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
int GapGetDeviceName(char *buf, size_t buf_size);
void GapClearDeviceName(void);
/*************************************************************************************************/
/*!
* \brief Perform service and characteristic discovery for GAP service. Note that pHdlList
* must point to an array of handles of length \ref GAP_HDL_LIST_LEN. If discovery is
* successful the handles of discovered characteristics and descriptors will be set
* in pHdlList.
*
* \param connId Connection identifier.
* \param pHdlList Characteristic handle list.
*
* \return None.
*/
/*************************************************************************************************/
void GapDiscover(dmConnId_t connId, uint16_t *pHdlList);
/*************************************************************************************************/
/*!
* \brief Process a value received in an ATT read response, notification, or indication
* message. Parameter pHdlList must point to an array of length \ref GAP_HDL_LIST_LEN.
* If the attribute handle of the message matches a handle in the handle list the value
* is processed, otherwise it is ignored.
*
* \param pHdlList Characteristic handle list.
* \param pMsg ATT callback message.
*
* \return \ref ATT_SUCCESS if handle is found, \ref ATT_ERR_NOT_FOUND otherwise.
*/
/*************************************************************************************************/
uint8_t GapValueUpdate(uint16_t *pHdlList, attEvt_t *pMsg);
/*! \} */ /* GAP_PROFILE */
#ifdef __cplusplus
};
#endif
#endif /* GAP_API_H */
/*************************************************************************************************/
/*!
* \file
*
* \brief GAP profile.
*
* Copyright (c) 2015-2018 Arm Ltd. All Rights Reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#include "wsf_types.h"
#include "wsf_assert.h"
#include "wsf_trace.h"
#include "app_db.h"
#include "app_api.h"
#include "gap_api.h"
#include <string.h>
/* card10:
* copied from lib/sdk/Libraries/BTLE/stack/ble-profiles/sources/profiles/gap/gap_main.c
*/
/* clang-format off */
/* clang-formet turned off for easier diffing against orginal file */
/**************************************************************************************************
Local Variables
**************************************************************************************************/
static char dn_value[ATT_DEFAULT_PAYLOAD_LEN + 1];
/*! GAP service characteristics for discovery */
static const attcDiscChar_t gapDn =
{
attDnChUuid,
0
};
/*! Central Address Resolution */
static const attcDiscChar_t gapCar =
{
attCarChUuid,
0
};
/*! Resolvable Private Address Only */
static const attcDiscChar_t gapRpao =
{
attRpaoChUuid,
0
};
/*! List of characteristics to be discovered; order matches handle index enumeration */
static const attcDiscChar_t *gapDiscCharList[] =
{
&gapDn,
&gapCar, /* Central Address Resolution */
&gapRpao /* Resolvable Private Address Only */
};
/* sanity check: make sure handle list length matches characteristic list length */
WSF_CT_ASSERT(GAP_HDL_LIST_LEN == ((sizeof(gapDiscCharList) / sizeof(attcDiscChar_t *))));
int GapGetDeviceName(char *buf, size_t buf_size)
{
memset(buf, 0, buf_size);
strncpy(buf, dn_value, buf_size - 1);
return 0;
}
void GapClearDeviceName(void)
{
dn_value[0] = 0;
}
/*************************************************************************************************/
/*!
* \brief Perform service and characteristic discovery for GAP service. Note that pHdlList
* must point to an array of handles of length GAP_HDL_LIST_LEN. If discovery is
* successful the handles of discovered characteristics and descriptors will be set
* in pHdlList.
*
* \param connId Connection identifier.
* \param pHdlList Characteristic handle list.
*
* \return None.
*/
/*************************************************************************************************/
void GapDiscover(dmConnId_t connId, uint16_t *pHdlList)
{
AppDiscFindService(connId, ATT_16_UUID_LEN, (uint8_t *) attGapSvcUuid,
GAP_HDL_LIST_LEN, (attcDiscChar_t **) gapDiscCharList, pHdlList);
}
/*************************************************************************************************/
/*!
* \brief Process a value received in an ATT read response, notification, or indication
* message. Parameter pHdlList must point to an array of length GAP_HDL_LIST_LEN.
* If the attribute handle of the message matches a handle in the handle list the value
* is processed, otherwise it is ignored.
*
* \param pHdlList Characteristic handle list.
* \param pMsg ATT callback message.
*
* \return ATT_SUCCESS if handle is found, ATT_ERR_NOT_FOUND otherwise.
*/
/*************************************************************************************************/
uint8_t GapValueUpdate(uint16_t *pHdlList, attEvt_t *pMsg)
{
uint8_t status = ATT_SUCCESS;
/* device name string */
if (pMsg->handle == pHdlList[GAP_DN_HDL_IDX])
{
int len = (pMsg->valueLen < (sizeof(dn_value) - 1)) ? pMsg->valueLen : (sizeof(dn_value) - 1);
memcpy(dn_value, pMsg->pValue, len);
dn_value[len] = '\0';
}
/* Central Address Resolution */
else if (pMsg->handle == pHdlList[GAP_CAR_HDL_IDX])
{
appDbHdl_t dbHdl;
/* if there's a device record */
if ((dbHdl = AppDbGetHdl((dmConnId_t)pMsg->hdr.param)) != APP_DB_HDL_NONE)
{
if ((pMsg->pValue[0] == FALSE) || (pMsg->pValue[0] == TRUE))
{
/* store value in device database */
AppDbSetPeerAddrRes(dbHdl, pMsg->pValue[0]);
}
else
{
/* invalid value */
status = ATT_ERR_RANGE;
}
APP_TRACE_INFO1("Central address resolution: %d", pMsg->pValue[0]);
}
}
/* handle not found in list */
else
{
status = ATT_ERR_NOT_FOUND;
}
return status;
}
/* clang-format on */
...@@ -156,6 +156,8 @@ typedef _Bool bool; ...@@ -156,6 +156,8 @@ typedef _Bool bool;
#define API_BLE_GET_EVENT 0x143 #define API_BLE_GET_EVENT 0x143
#define API_BLE_GET_SCAN_REPORT 0x144 #define API_BLE_GET_SCAN_REPORT 0x144
#define API_BLE_GET_LAST_PAIRING_NAME 0x145 #define API_BLE_GET_LAST_PAIRING_NAME 0x145
#define API_BLE_GET_PEER_DEVICE_NAME 0x146
/* clang-format on */ /* clang-format on */
...@@ -2249,6 +2251,21 @@ API(API_BLE_GET_COMPARE_VALUE, uint32_t epic_ble_get_compare_value(void)); ...@@ -2249,6 +2251,21 @@ API(API_BLE_GET_COMPARE_VALUE, uint32_t epic_ble_get_compare_value(void));
*/ */
API(API_BLE_GET_LAST_PAIRING_NAME, int epic_ble_get_last_pairing_name(char *buf, size_t buf_size)); API(API_BLE_GET_LAST_PAIRING_NAME, int epic_ble_get_last_pairing_name(char *buf, size_t buf_size));
/**
* Retrieve the name of the peer to which we are connected
*
* The name might be empty if the peer device does not expose it or
* if it has not yet been read from it.
*
* :return: `0` on success or a negative value if an error occured. Possible
* errors:
*
* - ``-ENOENT``: There is no active connection at the moment.
*
* .. versionadded:: 1.16
*/
API(API_BLE_GET_PEER_DEVICE_NAME, int epic_ble_get_peer_device_name(char *buf, size_t buf_size));
/** /**
* Indicate wether the user confirmed the compare value. * Indicate wether the user confirmed the compare value.
* *
......
...@@ -73,7 +73,7 @@ sources = files( ...@@ -73,7 +73,7 @@ sources = files(
'stack/ble-profiles/sources/profiles/wspc/wspc_main.c', 'stack/ble-profiles/sources/profiles/wspc/wspc_main.c',
'stack/ble-profiles/sources/profiles/hrpc/hrpc_main.c', 'stack/ble-profiles/sources/profiles/hrpc/hrpc_main.c',
'stack/ble-profiles/sources/profiles/uribeacon/uricfg_main.c', 'stack/ble-profiles/sources/profiles/uribeacon/uricfg_main.c',
'stack/ble-profiles/sources/profiles/gap/gap_main.c', #'stack/ble-profiles/sources/profiles/gap/gap_main.c',
'stack/ble-profiles/sources/profiles/glps/glps_db.c', 'stack/ble-profiles/sources/profiles/glps/glps_db.c',
'stack/ble-profiles/sources/profiles/glps/glps_main.c', 'stack/ble-profiles/sources/profiles/glps/glps_main.c',
'stack/ble-profiles/sources/profiles/fmpl/fmpl_main.c', 'stack/ble-profiles/sources/profiles/fmpl/fmpl_main.c',
......
...@@ -7,6 +7,12 @@ import interrupt ...@@ -7,6 +7,12 @@ import interrupt
import config import config
ble_event = None ble_event = None
is_active = False
STATE_IDLE = 1
STATE_NUMERIC_COMPARISON = 2
STATE_WAIT_FOR_COMPLETION = 3
STATE_FAIL = 4
def ble_callback(_): def ble_callback(_):
...@@ -36,7 +42,7 @@ def triangle(disp, x, y, left): ...@@ -36,7 +42,7 @@ def triangle(disp, x, y, left):
def toggle(): def toggle():
if is_active(): if is_active:
config.set_string("ble_enable", "false") config.set_string("ble_enable", "false")
else: else:
config.set_string("ble_enable", "true") config.set_string("ble_enable", "true")
...@@ -49,26 +55,21 @@ def toggle(): ...@@ -49,26 +55,21 @@ def toggle():
os.reset() os.reset()
def is_active():
try:
active = config.get_string("ble_enable")
if active == "true" or active == "1":
return True
except OSError:
pass
return False
def headline(): def headline():
disp.print("BLE", posy=0, fg=[0, 255, 255]) disp.print("BLE", posy=0, fg=[0, 255, 255])
if is_active(): if is_active:
disp.print("active", posy=20, fg=[0, 255, 0]) try:
dn = sys_ble.get_peer_device_name()
disp.print("Active", posy=0, posx=50, fg=[0, 255, 0])
disp.print(dn[:11], posy=20, posx=0, fg=[0, 255, 0])
except OSError:
disp.print("Ready", posy=0, posx=50, fg=[0, 255, 0])
mac = load_mac() mac = load_mac()
if mac is not None: if mac is not None:
disp.print(mac[9:], posy=60, fg=[0, 0, 255]) disp.print(mac[9:], posy=60, fg=[0, 0, 255])
else: else:
disp.print("inactive", posy=20, fg=[255, 0, 0]) disp.print("Off", posy=0, posx=50, fg=[255, 0, 0])
def selector(): def selector():
...@@ -76,9 +77,17 @@ def selector(): ...@@ -76,9 +77,17 @@ def selector():
disp.print("toggle", posx=25, posy=40, fg=[255, 255, 255]) disp.print("toggle", posx=25, posy=40, fg=[255, 255, 255])
try:
active = config.get_string("ble_enable")
if active.lower() == "true" or active == "1":
is_active = True
except OSError:
pass
init() init()
disp = display.open() disp = display.open()
state = 1 state = STATE_IDLE
v_old = buttons.read() v_old = buttons.read()
while True: while True:
...@@ -86,55 +95,57 @@ while True: ...@@ -86,55 +95,57 @@ while True:
v = ~v_old & v_new v = ~v_old & v_new
v_old = v_new v_old = v_new
if state == 1: if state == STATE_IDLE:
# print config screen # print config screen
disp.clear() disp.clear()
headline() headline()
selector() selector()
disp.update() disp.update()
state = 2
elif state == 2:
# wait for button press or ble_event # wait for button press or ble_event
if ble_event == sys_ble.EVENT_HANDLE_NUMERIC_COMPARISON: if ble_event == sys_ble.EVENT_HANDLE_NUMERIC_COMPARISON:
ble_event = None ble_event = None
state = 3 state = STATE_NUMERIC_COMPARISON
if v & buttons.TOP_RIGHT: if v & buttons.TOP_RIGHT:
toggle() toggle()
state = 1
elif state == 3: elif state == STATE_NUMERIC_COMPARISON:
# print confirmation value # print confirmation value
compare_value = sys_ble.get_compare_value() compare_value = sys_ble.get_compare_value()
disp.clear() disp.clear()
disp.print("BLE: Pair?", posy=0, fg=[0, 0, 255])
disp.print("Code:", posy=20, fg=[0, 255, 255]) try:
dn = sys_ble.get_peer_device_name()
disp.print(dn[:11], posy=0, fg=[0, 0, 255])
except OSError:
pass
disp.print("Pair Code:", posy=20, fg=[0, 255, 255])
disp.print(" %06d" % compare_value, posy=40, fg=[255, 255, 255]) disp.print(" %06d" % compare_value, posy=40, fg=[255, 255, 255])
disp.print("Yes", posy=60, fg=[0, 255, 0]) disp.print("Yes", posy=60, fg=[0, 255, 0])
disp.print("No", posx=120, posy=60, fg=[255, 0, 0]) disp.print("No", posx=120, posy=60, fg=[255, 0, 0])
disp.update() disp.update()
state = 4
elif state == 4:
# wait for button press or ble_event # wait for button press or ble_event
if ble_event == sys_ble.EVENT_PAIRING_FAILED: if ble_event == sys_ble.EVENT_PAIRING_FAILED:
ble_event = None ble_event = None
state = 6 state = STATE_FAIL
if v & buttons.BOTTOM_LEFT: if v & buttons.BOTTOM_LEFT:
sys_ble.confirm_compare_value(True) sys_ble.confirm_compare_value(True)
disp.clear() disp.clear()
disp.print("BLE Pairing", posy=0, fg=[0, 0, 255]) disp.print("BLE Pairing", posy=0, fg=[0, 0, 255])
disp.print("Please Wait", posy=40, fg=[255, 255, 255]) disp.print("Please Wait", posy=40, fg=[255, 255, 255])
disp.update() disp.update()
state = 5 state = STATE_WAIT_FOR_COMPLETION
elif v & (buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT): elif v & (buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT):
sys_ble.confirm_compare_value(False) sys_ble.confirm_compare_value(False)
state = 6 state = STATE_FAIL
elif state == 5: elif state == STATE_WAIT_FOR_COMPLETION:
# Wait for pairing to complete # Wait for pairing to complete
if ble_event == sys_ble.EVENT_PAIRING_FAILED: if ble_event == sys_ble.EVENT_PAIRING_FAILED:
ble_event = None ble_event = None
state = 6 state = STATE_FAIL
elif ble_event == sys_ble.EVENT_PAIRING_COMPLETE: elif ble_event == sys_ble.EVENT_PAIRING_COMPLETE:
ble_event = None ble_event = None
pairing_name = sys_ble.get_last_pairing_name().split("/")[-1].split(".")[0] pairing_name = sys_ble.get_last_pairing_name().split("/")[-1].split(".")[0]
...@@ -147,13 +158,13 @@ while True: ...@@ -147,13 +158,13 @@ while True:
time.sleep(5) time.sleep(5)
os.exec("main.py") os.exec("main.py")
elif state == 6: elif state == STATE_FAIL:
# display fail screen and wait 5 seconds # display fail screen and wait 5 seconds
disp.clear() disp.clear()
disp.print("BLE Pairing", posy=0, fg=[0, 0, 255]) disp.print("BLE Pairing", posy=0, fg=[0, 0, 255])
disp.print(" Fail", posy=40, fg=[255, 0, 0]) disp.print(" Fail", posy=40, fg=[255, 0, 0])
disp.update() disp.update()
time.sleep(5) time.sleep(5)
state = 1 state = STATE_IDLE
time.sleep(0.1) time.sleep(0.1)
...@@ -200,6 +200,7 @@ Q(BLE) ...@@ -200,6 +200,7 @@ Q(BLE)
Q(ble) Q(ble)
Q(get_compare_value)