User | Revision | Line number | New contents of line |
jinu |
0:6ba9b94b8997
|
1
|
/* Copyright (c) Nordic Semiconductor ASA
|
jinu |
0:6ba9b94b8997
|
2
|
* All rights reserved.
|
jinu |
0:6ba9b94b8997
|
3
|
*
|
jinu |
0:6ba9b94b8997
|
4
|
* Redistribution and use in source and binary forms, with or without modification,
|
jinu |
0:6ba9b94b8997
|
5
|
* are permitted provided that the following conditions are met:
|
jinu |
0:6ba9b94b8997
|
6
|
*
|
jinu |
0:6ba9b94b8997
|
7
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
jinu |
0:6ba9b94b8997
|
8
|
* list of conditions and the following disclaimer.
|
jinu |
0:6ba9b94b8997
|
9
|
*
|
jinu |
0:6ba9b94b8997
|
10
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
jinu |
0:6ba9b94b8997
|
11
|
* list of conditions and the following disclaimer in the documentation and/or
|
jinu |
0:6ba9b94b8997
|
12
|
* other materials provided with the distribution.
|
jinu |
0:6ba9b94b8997
|
13
|
*
|
jinu |
0:6ba9b94b8997
|
14
|
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
|
jinu |
0:6ba9b94b8997
|
15
|
* contributors to this software may be used to endorse or promote products
|
jinu |
0:6ba9b94b8997
|
16
|
* derived from this software without specific prior written permission.
|
jinu |
0:6ba9b94b8997
|
17
|
*
|
jinu |
0:6ba9b94b8997
|
18
|
* 4. This software must only be used in a processor manufactured by Nordic
|
jinu |
0:6ba9b94b8997
|
19
|
* Semiconductor ASA, or in a processor manufactured by a third party that
|
jinu |
0:6ba9b94b8997
|
20
|
* is used in combination with a processor manufactured by Nordic Semiconductor.
|
jinu |
0:6ba9b94b8997
|
21
|
*
|
jinu |
0:6ba9b94b8997
|
22
|
*
|
jinu |
0:6ba9b94b8997
|
23
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
jinu |
0:6ba9b94b8997
|
24
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
jinu |
0:6ba9b94b8997
|
25
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
jinu |
0:6ba9b94b8997
|
26
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
jinu |
0:6ba9b94b8997
|
27
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
jinu |
0:6ba9b94b8997
|
28
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
jinu |
0:6ba9b94b8997
|
29
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
jinu |
0:6ba9b94b8997
|
30
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
jinu |
0:6ba9b94b8997
|
31
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
jinu |
0:6ba9b94b8997
|
32
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
jinu |
0:6ba9b94b8997
|
33
|
*/
|
jinu |
0:6ba9b94b8997
|
34
|
|
jinu |
0:6ba9b94b8997
|
35
|
#include "ble_encode_access.h"
|
jinu |
0:6ba9b94b8997
|
36
|
#include "ble_encode_transport.h"
|
jinu |
0:6ba9b94b8997
|
37
|
#include <stdbool.h>
|
jinu |
0:6ba9b94b8997
|
38
|
#include <stdio.h>
|
jinu |
0:6ba9b94b8997
|
39
|
#include "ble.h"
|
jinu |
0:6ba9b94b8997
|
40
|
#include "ble_rpc_defines.h"
|
jinu |
0:6ba9b94b8997
|
41
|
#include "ble_app.h"
|
jinu |
0:6ba9b94b8997
|
42
|
#include "hal_transport.h"
|
jinu |
0:6ba9b94b8997
|
43
|
#include "nrf_error.h"
|
jinu |
0:6ba9b94b8997
|
44
|
#include "app_error.h"
|
jinu |
0:6ba9b94b8997
|
45
|
#include "compiler_abstraction.h"
|
jinu |
0:6ba9b94b8997
|
46
|
|
jinu |
0:6ba9b94b8997
|
47
|
static ble_command_resp_decode_callback_t m_cmd_resp_decode_callback; /**< BLE command response decode callback function. */
|
jinu |
0:6ba9b94b8997
|
48
|
static ble_encode_cmd_resp_handler_t m_ble_cmd_resp_handler; /**< BLE command response application callback function. */
|
jinu |
0:6ba9b94b8997
|
49
|
static ble_encode_event_handler_t m_ble_event_handler; /**< BLE event application callback function. */
|
jinu |
0:6ba9b94b8997
|
50
|
static const uint8_t * mp_evt_buffer; /**< Pointer to begin of received BLE event buffer. */
|
jinu |
0:6ba9b94b8997
|
51
|
static uint16_t m_evt_length; /**< Length of data in bytes in BLE event buffer. */
|
jinu |
0:6ba9b94b8997
|
52
|
static ble_encode_cmd_write_mode_t m_cmd_write_mode; /**< @ref ble_encode_transport_cmd_write API command mode. */
|
jinu |
0:6ba9b94b8997
|
53
|
static volatile uint32_t m_event_flags; /**< Variable for storing boolean event flags. */
|
jinu |
0:6ba9b94b8997
|
54
|
|
jinu |
0:6ba9b94b8997
|
55
|
#define FLAG_CMD_RESP_HANDLER_REGISTERED (1u << 0) /**< Flag for determining is command response handler registered or not. */
|
jinu |
0:6ba9b94b8997
|
56
|
#define FLAG_EVT_AVAILABLE_FOR_POP (1u << 1u) /**< Flag for determining is event available for application extraction. */
|
jinu |
0:6ba9b94b8997
|
57
|
#define FLAG_CMD_WRITE_INPROGRESS (1u << 2u) /**< Flag for determining is command write in progress. */
|
jinu |
0:6ba9b94b8997
|
58
|
|
jinu |
0:6ba9b94b8997
|
59
|
|
jinu |
0:6ba9b94b8997
|
60
|
/**@brief Function for processing BLE command response.
|
jinu |
0:6ba9b94b8997
|
61
|
*
|
jinu |
0:6ba9b94b8997
|
62
|
* @param[in] p_buffer Pointer to the begin of command response after packet type field.
|
jinu |
0:6ba9b94b8997
|
63
|
* @param[in] length Length of data in bytes.
|
jinu |
0:6ba9b94b8997
|
64
|
*/
|
jinu |
0:6ba9b94b8997
|
65
|
static __INLINE void ble_command_response_process(const uint8_t * p_buffer, uint32_t length)
|
jinu |
0:6ba9b94b8997
|
66
|
{
|
jinu |
0:6ba9b94b8997
|
67
|
// @note: System design does not allow any valid use case for the callback to be NULL
|
jinu |
0:6ba9b94b8997
|
68
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
69
|
APP_ERROR_CHECK_BOOL(m_cmd_resp_decode_callback != NULL);
|
jinu |
0:6ba9b94b8997
|
70
|
const uint32_t result_code = m_cmd_resp_decode_callback(p_buffer, length);
|
jinu |
0:6ba9b94b8997
|
71
|
|
jinu |
0:6ba9b94b8997
|
72
|
// @note: Relevant flags must be cleared before notifying the application of command response
|
jinu |
0:6ba9b94b8997
|
73
|
// reception due to the fact that application can call back within the same context.
|
jinu |
0:6ba9b94b8997
|
74
|
m_event_flags &= ~(FLAG_CMD_WRITE_INPROGRESS | FLAG_CMD_RESP_HANDLER_REGISTERED);
|
jinu |
0:6ba9b94b8997
|
75
|
|
jinu |
0:6ba9b94b8997
|
76
|
// @note: System design does not allow any valid use case for the callback to be NULL
|
jinu |
0:6ba9b94b8997
|
77
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
78
|
APP_ERROR_CHECK_BOOL(m_ble_cmd_resp_handler != NULL);
|
jinu |
0:6ba9b94b8997
|
79
|
m_ble_cmd_resp_handler(result_code);
|
jinu |
0:6ba9b94b8997
|
80
|
}
|
jinu |
0:6ba9b94b8997
|
81
|
|
jinu |
0:6ba9b94b8997
|
82
|
|
jinu |
0:6ba9b94b8997
|
83
|
/**@brief Function for processing BLE event.
|
jinu |
0:6ba9b94b8997
|
84
|
*
|
jinu |
0:6ba9b94b8997
|
85
|
* @param[in] p_buffer Pointer to the begin of event after packet type field.
|
jinu |
0:6ba9b94b8997
|
86
|
* @param[in] length Length of data in bytes.
|
jinu |
0:6ba9b94b8997
|
87
|
*/
|
jinu |
0:6ba9b94b8997
|
88
|
static __INLINE void ble_event_process(const uint8_t * p_buffer, uint32_t length)
|
jinu |
0:6ba9b94b8997
|
89
|
{
|
jinu |
0:6ba9b94b8997
|
90
|
// @note: System design does not allow any valid use case for the callback to be NULL
|
jinu |
0:6ba9b94b8997
|
91
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
92
|
APP_ERROR_CHECK_BOOL(m_ble_event_handler != NULL);
|
jinu |
0:6ba9b94b8997
|
93
|
|
jinu |
0:6ba9b94b8997
|
94
|
mp_evt_buffer = p_buffer;
|
jinu |
0:6ba9b94b8997
|
95
|
m_evt_length = length;
|
jinu |
0:6ba9b94b8997
|
96
|
|
jinu |
0:6ba9b94b8997
|
97
|
m_event_flags |= FLAG_EVT_AVAILABLE_FOR_POP;
|
jinu |
0:6ba9b94b8997
|
98
|
m_ble_event_handler(BLE_ENCODE_EVT_RDY);
|
jinu |
0:6ba9b94b8997
|
99
|
}
|
jinu |
0:6ba9b94b8997
|
100
|
|
jinu |
0:6ba9b94b8997
|
101
|
|
jinu |
0:6ba9b94b8997
|
102
|
/**@brief Function for processing RX packet ready event from transport layer.
|
jinu |
0:6ba9b94b8997
|
103
|
*/
|
jinu |
0:6ba9b94b8997
|
104
|
static __INLINE void rx_packet_ready_event_process(void)
|
jinu |
0:6ba9b94b8997
|
105
|
{
|
jinu |
0:6ba9b94b8997
|
106
|
uint8_t * p_buffer;
|
jinu |
0:6ba9b94b8997
|
107
|
uint16_t length;
|
jinu |
0:6ba9b94b8997
|
108
|
|
jinu |
0:6ba9b94b8997
|
109
|
// @note: This implementation is based on system design where max 1 RX buffer is available.
|
jinu |
0:6ba9b94b8997
|
110
|
// On any other design this system will fail as multiple received events can override existing
|
jinu |
0:6ba9b94b8997
|
111
|
// received event if application does not pop the event out within the current context.
|
jinu |
0:6ba9b94b8997
|
112
|
if (!(m_event_flags & FLAG_EVT_AVAILABLE_FOR_POP))
|
jinu |
0:6ba9b94b8997
|
113
|
{
|
jinu |
0:6ba9b94b8997
|
114
|
uint32_t err_code = hci_transport_rx_pkt_extract(&p_buffer, &length);
|
jinu |
0:6ba9b94b8997
|
115
|
// @note: System design does not allow any valid use case for the RX packet extract failure
|
jinu |
0:6ba9b94b8997
|
116
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
117
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
118
|
|
jinu |
0:6ba9b94b8997
|
119
|
const uint8_t packet_type = p_buffer[0]; // @todo: use #define for 0
|
jinu |
0:6ba9b94b8997
|
120
|
|
jinu |
0:6ba9b94b8997
|
121
|
switch (packet_type)
|
jinu |
0:6ba9b94b8997
|
122
|
{
|
jinu |
0:6ba9b94b8997
|
123
|
case BLE_RPC_PKT_RESP:
|
jinu |
0:6ba9b94b8997
|
124
|
case BLE_RPC_PKT_DTM_RESP:
|
jinu |
0:6ba9b94b8997
|
125
|
// Adjust buffer begin pointer and length values after bypassing the packet type
|
jinu |
0:6ba9b94b8997
|
126
|
// field.
|
jinu |
0:6ba9b94b8997
|
127
|
ble_command_response_process(&(p_buffer[1]), --length); // @todo: use #define for 1
|
jinu |
0:6ba9b94b8997
|
128
|
|
jinu |
0:6ba9b94b8997
|
129
|
// @todo: consider moving consume prior application completion event.
|
jinu |
0:6ba9b94b8997
|
130
|
err_code = hci_transport_rx_pkt_consume(p_buffer);
|
jinu |
0:6ba9b94b8997
|
131
|
// @note: System design does not allow any valid use case for the RX packet consume
|
jinu |
0:6ba9b94b8997
|
132
|
// failure which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
133
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
134
|
break;
|
jinu |
0:6ba9b94b8997
|
135
|
|
jinu |
0:6ba9b94b8997
|
136
|
case BLE_RPC_PKT_EVT:
|
jinu |
0:6ba9b94b8997
|
137
|
// Adjust buffer begin pointer and length values after bypassing the packet type
|
jinu |
0:6ba9b94b8997
|
138
|
// field.
|
jinu |
0:6ba9b94b8997
|
139
|
ble_event_process(&(p_buffer[1]), --length); // @todo: use #define for 1
|
jinu |
0:6ba9b94b8997
|
140
|
break;
|
jinu |
0:6ba9b94b8997
|
141
|
|
jinu |
0:6ba9b94b8997
|
142
|
default:
|
jinu |
0:6ba9b94b8997
|
143
|
// @note: Should never happen.
|
jinu |
0:6ba9b94b8997
|
144
|
APP_ERROR_HANDLER(packet_type);
|
jinu |
0:6ba9b94b8997
|
145
|
break;
|
jinu |
0:6ba9b94b8997
|
146
|
}
|
jinu |
0:6ba9b94b8997
|
147
|
}
|
jinu |
0:6ba9b94b8997
|
148
|
else
|
jinu |
0:6ba9b94b8997
|
149
|
{
|
jinu |
0:6ba9b94b8997
|
150
|
// @note: Should never happen.
|
jinu |
0:6ba9b94b8997
|
151
|
APP_ERROR_HANDLER(m_event_flags);
|
jinu |
0:6ba9b94b8997
|
152
|
}
|
jinu |
0:6ba9b94b8997
|
153
|
}
|
jinu |
0:6ba9b94b8997
|
154
|
|
jinu |
0:6ba9b94b8997
|
155
|
|
jinu |
0:6ba9b94b8997
|
156
|
/**@brief Function for processing events from transport layer.
|
jinu |
0:6ba9b94b8997
|
157
|
*
|
jinu |
0:6ba9b94b8997
|
158
|
* @param[in] event Transport layer event to process.
|
jinu |
0:6ba9b94b8997
|
159
|
*/
|
jinu |
0:6ba9b94b8997
|
160
|
static void transport_event_process(hci_transport_evt_t event)
|
jinu |
0:6ba9b94b8997
|
161
|
{
|
jinu |
0:6ba9b94b8997
|
162
|
switch (event.evt_type)
|
jinu |
0:6ba9b94b8997
|
163
|
{
|
jinu |
0:6ba9b94b8997
|
164
|
case HCI_TRANSPORT_RX_RDY:
|
jinu |
0:6ba9b94b8997
|
165
|
rx_packet_ready_event_process();
|
jinu |
0:6ba9b94b8997
|
166
|
break;
|
jinu |
0:6ba9b94b8997
|
167
|
case HCI_TRANSPORT_RX_STARTED:
|
jinu |
0:6ba9b94b8997
|
168
|
break;
|
jinu |
0:6ba9b94b8997
|
169
|
default:
|
jinu |
0:6ba9b94b8997
|
170
|
// @note: Should never happen.
|
jinu |
0:6ba9b94b8997
|
171
|
APP_ERROR_HANDLER(event.evt_type);
|
jinu |
0:6ba9b94b8997
|
172
|
break;
|
jinu |
0:6ba9b94b8997
|
173
|
}
|
jinu |
0:6ba9b94b8997
|
174
|
}
|
jinu |
0:6ba9b94b8997
|
175
|
|
jinu |
0:6ba9b94b8997
|
176
|
|
jinu |
0:6ba9b94b8997
|
177
|
/**@brief Function for processing TX done event from transport layer.
|
jinu |
0:6ba9b94b8997
|
178
|
*
|
jinu |
0:6ba9b94b8997
|
179
|
* @param[in] result TX done event result code.
|
jinu |
0:6ba9b94b8997
|
180
|
*/
|
jinu |
0:6ba9b94b8997
|
181
|
static void transport_tx_done_process(hci_transport_tx_done_result_t result)
|
jinu |
0:6ba9b94b8997
|
182
|
{
|
jinu |
0:6ba9b94b8997
|
183
|
APP_ERROR_CHECK_BOOL(result == HCI_TRANSPORT_TX_DONE_SUCCESS);
|
jinu |
0:6ba9b94b8997
|
184
|
|
jinu |
0:6ba9b94b8997
|
185
|
// Actions are only executed if no command response is required for the transmitted command.
|
jinu |
0:6ba9b94b8997
|
186
|
if (m_cmd_write_mode == BLE_ENCODE_WRITE_MODE_NO_RESP)
|
jinu |
0:6ba9b94b8997
|
187
|
{
|
jinu |
0:6ba9b94b8997
|
188
|
// @note: System design does not allow any valid use case for the callback to be NULL
|
jinu |
0:6ba9b94b8997
|
189
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
190
|
APP_ERROR_CHECK_BOOL(m_cmd_resp_decode_callback != NULL);
|
jinu |
0:6ba9b94b8997
|
191
|
const uint32_t result_code = m_cmd_resp_decode_callback(NULL, 0);
|
jinu |
0:6ba9b94b8997
|
192
|
|
jinu |
0:6ba9b94b8997
|
193
|
// @note: Relevant flags must be cleared before notifying the application of command
|
jinu |
0:6ba9b94b8997
|
194
|
// processing completion due to the fact that application can call back within the same
|
jinu |
0:6ba9b94b8997
|
195
|
// context.
|
jinu |
0:6ba9b94b8997
|
196
|
m_event_flags &= ~(FLAG_CMD_WRITE_INPROGRESS | FLAG_CMD_RESP_HANDLER_REGISTERED);
|
jinu |
0:6ba9b94b8997
|
197
|
|
jinu |
0:6ba9b94b8997
|
198
|
// @note: System design does not allow any valid use case for the callback to be NULL
|
jinu |
0:6ba9b94b8997
|
199
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
200
|
APP_ERROR_CHECK_BOOL(m_ble_cmd_resp_handler != NULL);
|
jinu |
0:6ba9b94b8997
|
201
|
m_ble_cmd_resp_handler(result_code);
|
jinu |
0:6ba9b94b8997
|
202
|
}
|
jinu |
0:6ba9b94b8997
|
203
|
}
|
jinu |
0:6ba9b94b8997
|
204
|
|
jinu |
0:6ba9b94b8997
|
205
|
|
jinu |
0:6ba9b94b8997
|
206
|
uint32_t ble_encode_open(void)
|
jinu |
0:6ba9b94b8997
|
207
|
{
|
jinu |
0:6ba9b94b8997
|
208
|
uint32_t err_code = hci_transport_evt_handler_reg(transport_event_process);
|
jinu |
0:6ba9b94b8997
|
209
|
// @note: Should never fail.
|
jinu |
0:6ba9b94b8997
|
210
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
211
|
err_code = hci_transport_tx_done_register(transport_tx_done_process);
|
jinu |
0:6ba9b94b8997
|
212
|
// @note: Should never fail.
|
jinu |
0:6ba9b94b8997
|
213
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
214
|
|
jinu |
0:6ba9b94b8997
|
215
|
return hci_transport_open();
|
jinu |
0:6ba9b94b8997
|
216
|
}
|
jinu |
0:6ba9b94b8997
|
217
|
|
jinu |
0:6ba9b94b8997
|
218
|
|
jinu |
0:6ba9b94b8997
|
219
|
uint32_t ble_encode_close(void)
|
jinu |
0:6ba9b94b8997
|
220
|
{
|
jinu |
0:6ba9b94b8997
|
221
|
m_event_flags = 0;
|
jinu |
0:6ba9b94b8997
|
222
|
m_evt_length = 0;
|
jinu |
0:6ba9b94b8997
|
223
|
m_ble_cmd_resp_handler = NULL;
|
jinu |
0:6ba9b94b8997
|
224
|
m_cmd_resp_decode_callback = NULL;
|
jinu |
0:6ba9b94b8997
|
225
|
m_ble_event_handler = NULL;
|
jinu |
0:6ba9b94b8997
|
226
|
mp_evt_buffer = NULL;
|
jinu |
0:6ba9b94b8997
|
227
|
m_cmd_write_mode = BLE_ENCODE_WRITE_MODE_MAX;
|
jinu |
0:6ba9b94b8997
|
228
|
|
jinu |
0:6ba9b94b8997
|
229
|
return hci_transport_close();
|
jinu |
0:6ba9b94b8997
|
230
|
}
|
jinu |
0:6ba9b94b8997
|
231
|
|
jinu |
0:6ba9b94b8997
|
232
|
|
jinu |
0:6ba9b94b8997
|
233
|
uint32_t ble_encode_cmd_resp_handler_reg(ble_encode_cmd_resp_handler_t ble_command_resp_handler)
|
jinu |
0:6ba9b94b8997
|
234
|
{
|
jinu |
0:6ba9b94b8997
|
235
|
if (ble_command_resp_handler == NULL)
|
jinu |
0:6ba9b94b8997
|
236
|
{
|
jinu |
0:6ba9b94b8997
|
237
|
return NRF_ERROR_NULL;
|
jinu |
0:6ba9b94b8997
|
238
|
}
|
jinu |
0:6ba9b94b8997
|
239
|
|
jinu |
0:6ba9b94b8997
|
240
|
uint32_t err_code;
|
jinu |
0:6ba9b94b8997
|
241
|
|
jinu |
0:6ba9b94b8997
|
242
|
if (!(m_event_flags & FLAG_CMD_RESP_HANDLER_REGISTERED))
|
jinu |
0:6ba9b94b8997
|
243
|
{
|
jinu |
0:6ba9b94b8997
|
244
|
m_event_flags |= FLAG_CMD_RESP_HANDLER_REGISTERED;
|
jinu |
0:6ba9b94b8997
|
245
|
m_ble_cmd_resp_handler = ble_command_resp_handler;
|
jinu |
0:6ba9b94b8997
|
246
|
err_code = NRF_SUCCESS;
|
jinu |
0:6ba9b94b8997
|
247
|
}
|
jinu |
0:6ba9b94b8997
|
248
|
else
|
jinu |
0:6ba9b94b8997
|
249
|
{
|
jinu |
0:6ba9b94b8997
|
250
|
err_code = NRF_ERROR_BUSY;
|
jinu |
0:6ba9b94b8997
|
251
|
}
|
jinu |
0:6ba9b94b8997
|
252
|
|
jinu |
0:6ba9b94b8997
|
253
|
return err_code;
|
jinu |
0:6ba9b94b8997
|
254
|
}
|
jinu |
0:6ba9b94b8997
|
255
|
|
jinu |
0:6ba9b94b8997
|
256
|
|
jinu |
0:6ba9b94b8997
|
257
|
uint32_t ble_encode_evt_handler_register(ble_encode_event_handler_t ble_event_handler)
|
jinu |
0:6ba9b94b8997
|
258
|
{
|
jinu |
0:6ba9b94b8997
|
259
|
if (ble_event_handler == NULL)
|
jinu |
0:6ba9b94b8997
|
260
|
{
|
jinu |
0:6ba9b94b8997
|
261
|
return NRF_ERROR_NULL;
|
jinu |
0:6ba9b94b8997
|
262
|
}
|
jinu |
0:6ba9b94b8997
|
263
|
|
jinu |
0:6ba9b94b8997
|
264
|
m_ble_event_handler = ble_event_handler;
|
jinu |
0:6ba9b94b8997
|
265
|
|
jinu |
0:6ba9b94b8997
|
266
|
return NRF_SUCCESS;
|
jinu |
0:6ba9b94b8997
|
267
|
}
|
jinu |
0:6ba9b94b8997
|
268
|
|
jinu |
0:6ba9b94b8997
|
269
|
|
jinu |
0:6ba9b94b8997
|
270
|
uint8_t * ble_encode_transport_tx_alloc(void)
|
jinu |
0:6ba9b94b8997
|
271
|
{
|
jinu |
0:6ba9b94b8997
|
272
|
uint8_t * p_buffer;
|
jinu |
0:6ba9b94b8997
|
273
|
uint32_t err_code;
|
jinu |
0:6ba9b94b8997
|
274
|
|
jinu |
0:6ba9b94b8997
|
275
|
// This should be called only from main application context and not from interrupt, otherwise it
|
jinu |
0:6ba9b94b8997
|
276
|
// will block the system.
|
jinu |
0:6ba9b94b8997
|
277
|
do
|
jinu |
0:6ba9b94b8997
|
278
|
{
|
jinu |
0:6ba9b94b8997
|
279
|
err_code = hci_transport_tx_alloc(&p_buffer);
|
jinu |
0:6ba9b94b8997
|
280
|
|
jinu |
0:6ba9b94b8997
|
281
|
//__WFE();
|
jinu |
0:6ba9b94b8997
|
282
|
}
|
jinu |
0:6ba9b94b8997
|
283
|
while (err_code == NRF_ERROR_NO_MEM);
|
jinu |
0:6ba9b94b8997
|
284
|
|
jinu |
0:6ba9b94b8997
|
285
|
|
jinu |
0:6ba9b94b8997
|
286
|
return p_buffer;
|
jinu |
0:6ba9b94b8997
|
287
|
}
|
jinu |
0:6ba9b94b8997
|
288
|
|
jinu |
0:6ba9b94b8997
|
289
|
|
jinu |
0:6ba9b94b8997
|
290
|
void ble_encode_transport_tx_free(void)
|
jinu |
0:6ba9b94b8997
|
291
|
{
|
jinu |
0:6ba9b94b8997
|
292
|
const uint32_t err_code = hci_transport_tx_free();
|
jinu |
0:6ba9b94b8997
|
293
|
// @note: Should never fail.
|
jinu |
0:6ba9b94b8997
|
294
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
295
|
}
|
jinu |
0:6ba9b94b8997
|
296
|
|
jinu |
0:6ba9b94b8997
|
297
|
|
jinu |
0:6ba9b94b8997
|
298
|
void ble_encode_transport_cmd_write(const uint8_t * p_buffer,
|
jinu |
0:6ba9b94b8997
|
299
|
uint32_t length,
|
jinu |
0:6ba9b94b8997
|
300
|
ble_encode_cmd_write_mode_t cmd_write_mode,
|
jinu |
0:6ba9b94b8997
|
301
|
ble_command_resp_decode_callback_t cmd_resp_decode_callback)
|
jinu |
0:6ba9b94b8997
|
302
|
{
|
jinu |
0:6ba9b94b8997
|
303
|
APP_ERROR_CHECK_BOOL(!(m_event_flags & FLAG_CMD_WRITE_INPROGRESS));
|
jinu |
0:6ba9b94b8997
|
304
|
APP_ERROR_CHECK_BOOL(p_buffer != NULL);
|
jinu |
0:6ba9b94b8997
|
305
|
APP_ERROR_CHECK_BOOL(length != 0);
|
jinu |
0:6ba9b94b8997
|
306
|
APP_ERROR_CHECK_BOOL((cmd_write_mode == BLE_ENCODE_WRITE_MODE_RESP) ||
|
jinu |
0:6ba9b94b8997
|
307
|
(cmd_write_mode == BLE_ENCODE_WRITE_MODE_NO_RESP));
|
jinu |
0:6ba9b94b8997
|
308
|
APP_ERROR_CHECK_BOOL(cmd_resp_decode_callback != NULL);
|
jinu |
0:6ba9b94b8997
|
309
|
|
jinu |
0:6ba9b94b8997
|
310
|
m_event_flags |= FLAG_CMD_WRITE_INPROGRESS;
|
jinu |
0:6ba9b94b8997
|
311
|
m_cmd_write_mode = cmd_write_mode;
|
jinu |
0:6ba9b94b8997
|
312
|
m_cmd_resp_decode_callback = cmd_resp_decode_callback;
|
jinu |
0:6ba9b94b8997
|
313
|
|
jinu |
0:6ba9b94b8997
|
314
|
const uint32_t err_code = hci_transport_pkt_write(p_buffer, length);
|
jinu |
0:6ba9b94b8997
|
315
|
// @note: Should never fail as system design allows only 1 command to be in progress at any
|
jinu |
0:6ba9b94b8997
|
316
|
// time.
|
jinu |
0:6ba9b94b8997
|
317
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
318
|
}
|
jinu |
0:6ba9b94b8997
|
319
|
|
jinu |
0:6ba9b94b8997
|
320
|
|
jinu |
0:6ba9b94b8997
|
321
|
uint32_t ble_encode_event_pop(ble_evt_t * p_event, uint32_t * p_event_len)
|
jinu |
0:6ba9b94b8997
|
322
|
{
|
jinu |
0:6ba9b94b8997
|
323
|
uint32_t err_code;
|
jinu |
0:6ba9b94b8997
|
324
|
|
jinu |
0:6ba9b94b8997
|
325
|
if (p_event_len == NULL)
|
jinu |
0:6ba9b94b8997
|
326
|
{
|
jinu |
0:6ba9b94b8997
|
327
|
return NRF_ERROR_NULL;
|
jinu |
0:6ba9b94b8997
|
328
|
}
|
jinu |
0:6ba9b94b8997
|
329
|
|
jinu |
0:6ba9b94b8997
|
330
|
if (m_event_flags & FLAG_EVT_AVAILABLE_FOR_POP)
|
jinu |
0:6ba9b94b8997
|
331
|
{
|
jinu |
0:6ba9b94b8997
|
332
|
m_event_flags &= ~FLAG_EVT_AVAILABLE_FOR_POP;
|
jinu |
0:6ba9b94b8997
|
333
|
|
jinu |
0:6ba9b94b8997
|
334
|
err_code = ble_event_dec(mp_evt_buffer, m_evt_length, p_event, p_event_len);
|
jinu |
0:6ba9b94b8997
|
335
|
// @note: Should never happen.
|
jinu |
0:6ba9b94b8997
|
336
|
APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_DATA_SIZE));
|
jinu |
0:6ba9b94b8997
|
337
|
|
jinu |
0:6ba9b94b8997
|
338
|
if ((err_code == NRF_SUCCESS) && (p_event != NULL))
|
jinu |
0:6ba9b94b8997
|
339
|
{
|
jinu |
0:6ba9b94b8997
|
340
|
// @note: (p_event != NULL) check needs to be included in order to cover the p_event
|
jinu |
0:6ba9b94b8997
|
341
|
// length query use case.
|
jinu |
0:6ba9b94b8997
|
342
|
|
jinu |
0:6ba9b94b8997
|
343
|
// @note: Decrement buffer pointer to original received from
|
jinu |
0:6ba9b94b8997
|
344
|
// @ref hci_transport_rx_pkt_extract.
|
jinu |
0:6ba9b94b8997
|
345
|
--mp_evt_buffer;
|
jinu |
0:6ba9b94b8997
|
346
|
err_code = hci_transport_rx_pkt_consume((uint8_t *)mp_evt_buffer);
|
jinu |
0:6ba9b94b8997
|
347
|
// @note: System design does not allow any valid use case for the RX packet consume failure
|
jinu |
0:6ba9b94b8997
|
348
|
// which will imply design error that must be fixed at compile time.
|
jinu |
0:6ba9b94b8997
|
349
|
APP_ERROR_CHECK(err_code);
|
jinu |
0:6ba9b94b8997
|
350
|
}
|
jinu |
0:6ba9b94b8997
|
351
|
}
|
jinu |
0:6ba9b94b8997
|
352
|
else
|
jinu |
0:6ba9b94b8997
|
353
|
{
|
jinu |
0:6ba9b94b8997
|
354
|
err_code = NRF_ERROR_NO_MEM;
|
jinu |
0:6ba9b94b8997
|
355
|
}
|
jinu |
0:6ba9b94b8997
|
356
|
|
jinu |
0:6ba9b94b8997
|
357
|
return err_code;
|
jinu |
0:6ba9b94b8997
|
358
|
}
|
jinu |
0:6ba9b94b8997
|
359
|
|