Download as pdf or txt
Download as pdf or txt
You are on page 1of 50

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.

c
6/12/2013 10:02:24

1: /*******************************************************************************
*******************
2:
Filename:
hci_ext_app.c
3:
Revised:
$Date: 2012-10-04 13:45:02 -0700 (Thu, 04 Oct 2012) $
4:
Revision:
$Revision: 31701 $
5:
6:
Description:
HCI Extensions Application
7:
8:
9:
Copyright 2009-2012 Texas Instruments Incorporated. All rights reserved.
10:
11:
IMPORTANT: Your use of this Software is limited to those specific rights
12:
granted under the terms of a software license agreement between the user
13:
who downloaded the software, his/her employer (which must be your employer)
14:
and Texas Instruments Incorporated (the "License"). You may not use this
15:
Software unless you agree to abide by the terms of the License. The License
16:
limits your use, and you acknowledge, that the Software may not be modified,
17:
copied or distributed unless embedded on a Texas Instruments microcontroller
18:
or used solely and exclusively in conjunction with a Texas Instruments radio
19:
frequency transceiver, which is integrated into your product. Other than for
20:
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
21:
works of, modify, distribute, perform, display or sell this Software and/or
22:
its documentation for any purpose.
23:
24:
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
25:
PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
26:
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
27:
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
28:
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
29:
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
30:
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
31:
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
32:
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
33:
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
34:
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
35:
36:
Should you have any questions regarding your right to use this Software,
37:
contact Texas Instruments Incorporated at www.TI.com.
38: ********************************************************************************
******************/
39:
40: /*********************************************************************
41: * INCLUDES
42: */
43: #include "bcomdef.h"
44: #include "OSAL.h"
45: #include "hal_lcd.h"
46: #include "hci.h"
47: #include "hci_tl.h"
48: #include "l2cap.h"
49: #include "gap.h"
50: #include "gatt.h"
51: #include "gatt_uuid.h"
52: #include "osal_snv.h"
53:
54: #if !defined ( GATT_DB_OFF_CHIP )
55:
#include "gattservapp.h"
56:
#include "gapgattserver.h"
57:
58:
#if defined ( GATT_TEST ) || defined ( GATT_QUAL )
59:
#include "gatttest.h"
60:
#endif

1/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:

#endif // GATT_DB_OFF_CHIP
#if defined ( GAP_BOND_MGR )
#include "gapbondmgr.h"
#endif
#include "OnBoard.h"
#include "hci_ext_app.h"
#include "arbitraryService.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#define HCI_EXT_RESET_EVENT
#define HCI_EXT_SOFT_RESET_EVENT

0x0001
0x0002

#define RESET_TIMEOUT

100

#define RSP_PAYLOAD_IDX
#define MAX_RSP_DATA_LEN
#define MAX_RSP_BUF

6
50
( RSP_PAYLOAD_IDX + MAX_RSP_DATA_LEN )

#if !defined ( HCI_EXT_APP_OUT_BUF )


#define HCI_EXT_APP_OUT_BUF
#endif

40

#define
#define
#define
#define
#define
#define

0x01
0x02
0x04
0x08
0x10
0x20

KEYDIST_SENC
KEYDIST_SID
KEYDIST_SSIGN
KEYDIST_MENC
KEYDIST_MID
KEYDIST_MSIGN

#define HCI_EXT_HDR_LEN

// 100 milliseconds

// Maximum number of reliable writes supported by Attribute Client


#define GATT_MAX_NUM_RELIABLE_WRITES
5
/*********************************************************************
* TYPEDEFS
*/
typedef struct
{
uint8 pktType;
uint16 opCode;
uint8 len;
uint8 *pData;
} hciExtCmd_t;
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/

2/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:

/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
uint8 hciExtApp_TaskID;
// Task ID for internal task/event processing
uint32 hciExtSignCounter = 0;
static uint8 out_msg[HCI_EXT_APP_OUT_BUF];
uint8 rspBuf[MAX_RSP_BUF];
// The device's local keys
static uint8 IRK[KEYLEN] = {0};
static uint8 SRK[KEYLEN] = {0};
#if !defined ( GATT_DB_OFF_CHIP )
#if ( ( HOST_CONFIG & CENTRAL_CFG ) && ( HOST_CONFIG
static uint8 deviceName[GAP_DEVICE_NAME_LEN] = "TI
#elif ( HOST_CONFIG & CENTRAL_CFG )
static uint8 deviceName[GAP_DEVICE_NAME_LEN] = "TI
#else
static uint8 deviceName[GAP_DEVICE_NAME_LEN] = "TI
#endif
static uint16 appearance = 17;
#endif

& PERIPHERAL_CFG ) )
BLE All";
BLE Central";
BLE Peripheral";

#if defined ( GAP_BOND_MGR )


static uint8 hciExtProfileRole;
#endif

/*********************************************************************
* LOCAL FUNCTIONS
*/
/*********************************************************************
* NETWORK LAYER CALLBACKS
*/
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* LOCAL FUNCTION PROTOTYPES
*/
static uint8 processExtMsg( hciPacket_t *pMsg );

static uint8 processExMsgPROFILE( uint8 cmdID, hciExtCmd_t *pCmd, uint8


*pRspDataLen );
176: static void arbitraryServiceChangeCB( uint8 paramID, uint16 len, uint16
connHandle );
177:
178: static uint8 processExMsgUTIL( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen );
179: static uint8 checkNVLen( osalSnvId_t id, osalSnvLen_t len );
180: static uint8 processExMsgL2CAP( uint8 cmdID, hciExtCmd_t *pCmd );
181: static uint8 processExMsgATT( uint8 cmdID, hciExtCmd_t *pCmd );

3/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

182: static uint8 processExMsgGATT( uint8 cmdID, hciExtCmd_t *pCmd, uint8


*pRspDataLen );
183: static uint8 processExMsgGAP( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen );
184:
185: static uint8 processEvents( osal_event_hdr_t *pMsg );
186: static uint8 *processEventsGAP( gapEventHdr_t *pMsg, uint8 *pOutMsg, uint8
*pMsgLen, uint8 *pAllocated );
187: static uint8 *processEventsL2CAP( l2capSignalEvent_t *pPkt, uint8 *pOutMsg,
uint8 *pMsgLen );
188: static uint8 *processEventsGATT( gattMsgEvent_t *pPkt, uint8 *pMsg, uint8
*pMsgLen, uint8 *pAllocated );
189:
190: #ifndef GATT_DB_OFF_CHIP
191: static uint8 *processEventsGATTServ( gattEventHdr_t *pPkt, uint8 *pMsg, uint8
*pMsgLen );
192: #else
193: static uint8 addAttrRec( gattService_t *pServ, uint8 *pUUID, uint8 len,
194:
uint8 permissions, uint16 *pTotalAttrs, uint8
*pRspDataLen );
195: static void freeAttrRecs( gattService_t *pServ );
196: static const uint8 *findUUIDRec( uint8 *pUUID, uint8 len );
197: #endif // !GATT_DB_OFF_CHIP
198:
199: static uint8 buildHCIExtHeader( uint8 *pBuf, uint16 event, uint8 status, uint16
connHandle );
200: static uint8 mapATT2BLEStatus( uint8 status );
201:
202:
203:
204: // Arbitrary Service Callbacks
205: static arbitraryServiceCBs_t hci_ext_ArbitraryServiceCBs =
206: {
207:
arbitraryServiceChangeCB
208: };
209:
210:
211: /*********************************************************************
212: * @fn
HCI_EXT_App_Init
213: *
214: * @brief
Initialization function for the HCI Ext App Task.
215: *
This is called during initialization and should contain
216: *
any application specific initialization (ie. hardware
217: *
initialization/setup, table initialization, power up
218: *
notificaiton ... ).
219: *
220: * @param
task_id - the ID assigned by OSAL. This ID should be
221: *
used to send messages and set timers.
222: *
223: * @return none
224: */
225: void HCI_EXT_App_Init( uint8 task_id )
226: {
227:
hciExtApp_TaskID = task_id;
228:
229:
HCI_ExtTaskRegister( hciExtApp_TaskID );
230:
231:
// Register for unwanted HCI messages
232:
GAP_RegisterForHCIMsgs( hciExtApp_TaskID );
233:
234:
// Initialize GATT Client
235:
VOID GATT_InitClient();

4/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

236:
237:
// Register to receive incoming ATT Indications/Notifications
238:
GATT_RegisterForInd( hciExtApp_TaskID );
239:
240: #if !defined ( GATT_DB_OFF_CHIP )
241:
// Register with GATT Server App for event messages
242:
GATTServApp_RegisterForMsg( hciExtApp_TaskID );
243:
244:
#if defined ( GATT_QUAL )
245:
VOID GATTQual_AddService( GATT_ALL_SERVICES ); // Includes GAP and GATT
Services
246:
#else
247:
// Add our services to GATT Server
248:
VOID GGS_AddService( GATT_ALL_SERVICES );
249:
VOID GATTServApp_AddService( GATT_ALL_SERVICES );
250:
#if defined ( GATT_TEST )
251:
VOID GATTTest_AddService( GATT_ALL_SERVICES );
252:
#endif
253:
#endif
254:
255:
VOID GGS_SetParameter( GGS_DEVICE_NAME_ATT, osal_strlen((char *)deviceName) ,
deviceName );
256:
VOID GGS_SetParameter( GGS_APPEARANCE_ATT, sizeof( uint16 ),
(void*)&appearance );
257: #else
258:
// Register with GATT Server for GATT messages
259:
GATT_RegisterForReq( hciExtApp_TaskID );
260: #endif // GATT_DB_OFF_CHIP
261:
262:
263: #if (defined HAL_LCD) && (HAL_LCD == TRUE)
264:
265:
HalLcdWriteString( " TI BLEv1.3", HAL_LCD_LINE_1 );
266:
HalLcdWriteString( " HostTestApp", HAL_LCD_LINE_2 );
267:
#if ( ( HOST_CONFIG & CENTRAL_CFG ) && ( HOST_CONFIG & PERIPHERAL_CFG ) )
268:
HalLcdWriteString( "
All", HAL_LCD_LINE_3 );
269:
#elif ( ( HOST_CONFIG & CENTRAL_CFG ) && ( HOST_CONFIG & BROADCASTER_CFG ) )
270:
HalLcdWriteString( " Cent+Bcast", HAL_LCD_LINE_3 );
271:
#elif ( ( HOST_CONFIG & PERIPHERAL_CFG ) && ( HOST_CONFIG & OBSERVER_CFG ) )
272:
HalLcdWriteString( " Peri+Observ", HAL_LCD_LINE_3 );
273:
#elif ( HOST_CONFIG & CENTRAL_CFG )
274:
HalLcdWriteString( "
Central", HAL_LCD_LINE_3 );
275:
#else
276:
HalLcdWriteString( " Peripheral", HAL_LCD_LINE_3 );
277:
#endif
278:
279: #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
280:
281:
282:
283:
VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, IRK );
284:
VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, SRK );
285:
VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ),
&hciExtSignCounter );
286: }
287:
288: /*********************************************************************
289: * @fn
HCI_EXT_App_ProcessEvent
290: *
291: * @brief
HCI Extension App Task event processor. This function
292: *
is called to process all events for the task. Events
293: *
include timers, messages and any other user defined events.

5/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

294: *
295: * @param
task_id - The OSAL assigned task ID.
296: * @param
events - events to process. This is a bit map and can
297: *
contain more than one event.
298: *
299: * @return none
300: */
301: uint16 HCI_EXT_App_ProcessEvent( uint8 task_id, uint16 events )
302: {
303:
if ( events & SYS_EVENT_MSG )
304:
{
305:
hciPacket_t *pMsg;
306:
307:
if ( (pMsg = ( hciPacket_t *)osal_msg_receive( hciExtApp_TaskID )) != NULL )
308:
{
309:
uint8 dealloc = TRUE;
310:
311:
// Process incoming messages
312:
switch ( pMsg->hdr.event )
313:
{
314:
// Incoming HCI extension message
315:
case HCI_EXT_CMD_EVENT:
316:
dealloc = processExtMsg( pMsg );
317:
break;
318:
319:
case HCI_GAP_EVENT_EVENT:
320:
{
321:
if ( pMsg->hdr.status == HCI_COMMAND_COMPLETE_EVENT_CODE )
322:
{
323:
hciEvt_CmdComplete_t *pkt = (hciEvt_CmdComplete_t *)pMsg;
324:
osal_msg_hdr_t *msgHdr;
325:
uint8 len;
326:
327:
msgHdr = (osal_msg_hdr_t *)pMsg;
328:
msgHdr--; // Backup to the msg header
329:
330:
len = (uint8)(msgHdr->len - sizeof ( hciEvt_CmdComplete_t ));
331:
332:
HCI_SendCommandCompleteEvent( HCI_COMMAND_COMPLETE_EVENT_CODE,
pkt->cmdOpcode, len, pkt->pReturnParam );
333:
}
334:
}
335:
break;
336:
337:
default:
338:
dealloc = processEvents( (osal_event_hdr_t *)pMsg );
339:
break;
340:
}
341:
342:
// Release the OSAL message
343:
if ( dealloc )
344:
{
345:
VOID osal_msg_deallocate( (uint8 *)pMsg );
346:
}
347:
}
348:
349:
// return unprocessed events
350:
return (events ^ SYS_EVENT_MSG);
351:
}
352:
353:
if ( events & GAP_EVENT_SIGN_COUNTER_CHANGED )
354:
{

6/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:

// Sign counter changed, save it to NV


VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ),
&hciExtSignCounter );
return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
}
if ( events & HCI_EXT_RESET_EVENT )
{
SystemReset();

// Because of the reset, processing will not return here


// return ( events ^ HCI_EXT_RESET_EVENT ); // Commented out to remove the
warning
367:
}
368:
369:
if ( events & HCI_EXT_SOFT_RESET_EVENT )
370:
{
371:
SystemResetSoft(); // Will not break comm with USB Host.
372:
373:
// Because of the reset, processing will not return here
374:
return ( events ^ HCI_EXT_SOFT_RESET_EVENT );
375:
}
376:
377:
// Discard unknown events
378:
return 0;
379: }
380:
381: /*********************************************************************
382: * @fn
processExtMsg
383: *
384: * @brief
Parse and process incoming HCI extension messages.
385: *
386: * @param
pMsg - incoming HCI extension message.
387: *
388: * @return none
389: */
390: static uint8 processExtMsg( hciPacket_t *pMsg )
391: {
392:
uint8 deallocateIncoming;
393:
bStatus_t stat = SUCCESS;
394:
uint8 rspDataLen = 0;
395:
hciExtCmd_t msg;
396:
uint8 *pBuf = pMsg->pData;
397:
398:
// Parse the header
399:
msg.pktType = *pBuf++;
400:
msg.opCode = BUILD_UINT16( pBuf[0], pBuf[1] );
401:
pBuf += 2;
402:
403:
msg.len = *pBuf++;
404:
msg.pData = pBuf;
405:
406:
switch( msg.opCode >> 7 )
407:
{
408:
case HCI_EXT_L2CAP_SUBGRP:
409:
stat = processExMsgL2CAP( (msg.opCode & 0x007F), &msg );
410:
break;
411:
412:
case HCI_EXT_ATT_SUBGRP:
413:
stat = processExMsgATT( (msg.opCode & 0x007F), &msg );
414:
break;

7/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

415:
416:
case HCI_EXT_GATT_SUBGRP:
417:
stat = processExMsgGATT( (msg.opCode & 0x007F), &msg, &rspDataLen );
418:
break;
419:
420:
case HCI_EXT_GAP_SUBGRP:
421:
stat = processExMsgGAP( (msg.opCode & 0x007F), &msg, &rspDataLen );
422:
break;
423:
424:
case HCI_EXT_UTIL_SUBGRP:
425:
stat = processExMsgUTIL( (msg.opCode & 0x007F), &msg, &rspDataLen );
426:
break;
427:
428:
case HCI_EXT_PROFILE_SUBGRP:
429:
stat = processExMsgPROFILE( (msg.opCode & 0x007F), &msg, &rspDataLen );
430:
break;
431:
432:
433:
default:
434:
stat = FAILURE;
435:
break;
436:
}
437:
438:
// Deallocate here to free up heap space for the serial message set out HCI.
439:
VOID osal_msg_deallocate( (uint8 *)pMsg );
440:
deallocateIncoming = FALSE;
441:
442:
// Send back an immediate response
443:
rspBuf[0] = LO_UINT16( HCI_EXT_GAP_CMD_STATUS_EVENT );
444:
rspBuf[1] = HI_UINT16( HCI_EXT_GAP_CMD_STATUS_EVENT );
445:
rspBuf[2] = stat;
446:
rspBuf[3] = LO_UINT16( 0xFC00 | msg.opCode );
447:
rspBuf[4] = HI_UINT16( 0xFC00 | msg.opCode );
448:
rspBuf[5] = rspDataLen;
449:
450:
// IMPORTANT!! Fill in Payload (if needed) in case statement
451:
452:
HCI_SendControllerToHostEvent( HCI_VE_EVENT_CODE, (6 + rspDataLen), rspBuf );
453:
454:
return ( deallocateIncoming );
455: }
456:
457: /*********************************************************************
458: * @fn
processExMsgPROFILE
459: *
460: * @brief
Parse and process incoming HCI extension PROFILE messages.
461: *
462: * @param
cmdID - incoming HCI extension command ID.
463: * @param
pCmd - incoming HCI extension message.
464: * @param
pRspDataLen - response data length to be returned.
465: *
466: * @return SUCCESS, INVALIDPARAMETER and FAILURE.
467: */
468: static uint8 processExMsgPROFILE( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen )
469: {
470:
bStatus_t stat = SUCCESS;
471:
472:
*pRspDataLen = 0;
473:
474:
switch( cmdID )
475:
{

8/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

476:
case HCI_EXT_PROFILE_ADD_ARB_SVC:
477:
stat = ArbitraryService_AddService( );
478:
break;
479:
480:
481:
case HCI_EXT_PROFILE_REG_WRT_CB:
482:
stat = ArbitraryService_RegisterAppCBs( &hci_ext_ArbitraryServiceCBs );
483:
break;
484:
485:
486:
case HCI_EXT_PROFILE_SETPARAM:
487:
{
488:
uint8 param = pCmd->pData[0];
489:
uint8 len = pCmd->len - 1;
490:
uint8 *value = &pCmd->pData[1];
491:
492:
if ( len > 0 )
493:
stat = ArbitraryService_SetParameter( param, len, (void *)value );
494:
else
495:
stat = INVALIDPARAMETER;
496:
}
497:
break;
498:
499:
case HCI_EXT_PROFILE_GETPARAM:
500:
{
501:
uint8 param = pCmd->pData[0]; // Which parameter
502:
uint8 len = pCmd->pData[1]; // Need to know how much to return
503:
stat = ArbitraryService_GetParameter( param, (void *)(rspBuf+6) );
504:
if (stat == SUCCESS)
505:
*pRspDataLen = len;
506:
else
507:
stat = INVALIDPARAMETER;
508:
}
509:
break;
510:
511:
default:
512:
stat = FAILURE;
513:
break;
514:
}
515:
516:
return ( stat );
517: }
518:
519: static void arbitraryServiceChangeCB( uint8 paramID, uint16 len, uint16
connHandle )
520: {
521: // Send an event.
522:
uint8 msgLen = 0;
523:
// Build the message header first
524:
msgLen = buildHCIExtHeader( out_msg, (HCI_EXT_PROFILE_EVENT | 0x01), //
0x0781 event code, randomly chosen.
525:
SUCCESS, connHandle ); // Always success, always
conn handle 0.
526:
527:
ArbitraryService_GetParameter( paramID, (void *)(out_msg + msgLen) );
528:
msgLen += len;
529:
530:
HCI_SendControllerToHostEvent( HCI_VE_EVENT_CODE, msgLen, out_msg );
531:
532: }
533:
534:

9/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

535: /*********************************************************************
536: * @fn
processExMsgUTIL
537: *
538: * @brief
Parse and process incoming HCI extension UTIL messages.
539: *
540: * @param
cmdID - incoming HCI extension command ID.
541: * @param
pCmd - incoming HCI extension message.
542: * @param
pRspDataLen - response data length to be returned.
543: *
544: * @return SUCCESS, INVALIDPARAMETER and FAILURE.
545: */
546: static uint8 processExMsgUTIL( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen )
547: {
548:
uint8 *pBuf = pCmd->pData;
549:
bStatus_t stat = SUCCESS;
550:
551:
*pRspDataLen = 0;
552:
553:
switch( cmdID )
554:
{
555:
case HCI_EXT_UTIL_RESET:
556:
if ( pBuf[0] == 0 )
557:
{
558:
VOID osal_start_timerEx( hciExtApp_TaskID, HCI_EXT_RESET_EVENT,
(uint32)RESET_TIMEOUT );
559:
}
560:
else
561:
{
562:
VOID osal_start_timerEx( hciExtApp_TaskID, HCI_EXT_SOFT_RESET_EVENT,
(uint32)RESET_TIMEOUT );
563:
}
564:
break;
565:
566:
case HCI_EXT_UTIL_NV_READ:
567:
{
568:
osalSnvId_t id = pBuf[0];
569:
osalSnvLen_t len = pBuf[1];
570:
571:
// This has a limitation of only allowing a max data length because of
the fixed buffer.
572:
if ( (len < MAX_RSP_DATA_LEN) && (checkNVLen( id, len ) == SUCCESS) )
573:
{
574:
stat = osal_snv_read( id, len, &rspBuf[RSP_PAYLOAD_IDX] );
575:
if ( stat == SUCCESS )
576:
{
577:
*pRspDataLen = pBuf[1];
578:
}
579:
}
580:
else
581:
{
582:
stat = INVALIDPARAMETER;
583:
}
584:
}
585:
break;
586:
587:
case HCI_EXT_UTIL_NV_WRITE:
588:
{
589:
osalSnvId_t id = pBuf[0];
590:
osalSnvLen_t len = pBuf[1];
591:
if ( checkNVLen( id, len ) == SUCCESS )
592:
{

10/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

593:
594:
595:
596:
597:

stat = osal_snv_write( id, len, &pBuf[2] );


if ( id == BLE_NVID_SIGNCOUNTER )
{
hciExtSignCounter = BUILD_UINT32(pBuf[2], pBuf[3], pBuf[4],
pBuf[5]);

598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:

}
}
else
{
stat = INVALIDPARAMETER;
}
}
break;
case HCI_EXT_UTIL_FORCE_BOOT:
{
extern void appForceBoot(void);
appForceBoot();
// Should never get here if SBL is present
stat = INVALIDPARAMETER;
}
break;
default:
stat = FAILURE;
break;
}
return ( stat );
}
/*********************************************************************
* @fn
checkNVLen
*
* @brief
Checks the size of NV items.
*
* @param
id - NV ID.
* @param
len - lengths in bytes of item.
*
* @return SUCCESS, INVALIDPARAMETER or FAILURE
*/
static uint8 checkNVLen( osalSnvId_t id, osalSnvLen_t len )
{
uint8 stat = SUCCESS;
switch
{
case
case
if
{

( id )
BLE_NVID_CSRK:
BLE_NVID_IRK:
( len != KEYLEN )

stat = INVALIDPARAMETER;
}
break;
case BLE_NVID_SIGNCOUNTER:
if ( len != sizeof ( uint32 ) )
{
stat = INVALIDPARAMETER;
}

11/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685:
686:
687:
688:
689:
690:
691:
692:
693:

break;
default:
stat = INVALIDPARAMETER;

// Initialize status to failure

#if defined ( GAP_BOND_MGR )


if ( (id >= BLE_NVID_GAP_BOND_START) && (id <= BLE_NVID_GAP_BOND_END) )
{
stat = GAPBondMgr_CheckNVLen( id, len );
}
#endif
break;
}
return ( stat );
}
/*********************************************************************
* @fn
processExMsgL2CAP
*
* @brief
Parse and process incoming HCI extension L2CAP messages.
*
* @param
pCmd - incoming HCI extension message.
*
* @return SUCCESS or FAILURE
*/
static uint8 processExMsgL2CAP( uint8 cmdID, hciExtCmd_t *pCmd )
{
uint8 *pBuf = pCmd->pData;
uint16 connHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
l2capSignalCmd_t cmd;
bStatus_t stat;

switch( cmdID )
{
case L2CAP_PARAM_UPDATE_REQ:
stat = L2CAP_ParseParamUpdateReq( &cmd, &pBuf[2], pCmd->len-2 );
if ( stat == SUCCESS )
{
stat = L2CAP_ConnParamUpdateReq( connHandle, &cmd.updateReq,
hciExtApp_TaskID );
694:
}
695:
break;
696:
697:
case L2CAP_INFO_REQ:
698:
stat = L2CAP_ParseInfoReq( &cmd, &pBuf[2], pCmd->len-2 );
699:
if ( stat == SUCCESS )
700:
{
701:
stat = L2CAP_InfoReq( connHandle, &cmd.infoReq, hciExtApp_TaskID );
702:
}
703:
break;
704:
705:
default:
706:
stat = FAILURE;
707:
break;
708:
}
709:
710:
return ( stat );
711: }
712:
713: /*********************************************************************
714: * @fn
processExMsgATT

12/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

715: *
716: * @brief
Parse and process incoming HCI extension ATT messages.
717: *
718: * @param
pCmd - incoming HCI extension message.
719: *
720: * @return SUCCESS, INVALIDPARAMETER, FAILURE,
721: *
bleInvalidPDU, bleInsufficientAuthen,
722: *
bleInsufficientKeySize, bleInsufficientEncrypt or bleMemAllocError
723: */
724: static uint8 processExMsgATT( uint8 cmdID, hciExtCmd_t *pCmd )
725: {
726:
static uint8 numPrepareWrites = 0;
727:
static attPrepareWriteReq_t *pPrepareWrites = NULL;
728:
uint8 *pBuf = pCmd->pData;
729:
uint16 connHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
730:
attMsg_t msg;
731:
bStatus_t stat;
732:
733:
switch( cmdID )
734:
{
735:
case ATT_ERROR_RSP:
736:
stat = ATT_ParseErrorRsp( &pBuf[2], pCmd->len-2, &msg );
737:
if ( stat == SUCCESS )
738:
{
739:
stat = ATT_ErrorRsp( connHandle, &msg.errorRsp );
740:
}
741:
break;
742:
743:
case ATT_EXCHANGE_MTU_REQ:
744:
stat = ATT_ParseExchangeMTUReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
745:
if ( stat == SUCCESS )
746:
{
747:
stat = GATT_ExchangeMTU( connHandle, &msg.exchangeMTUReq,
hciExtApp_TaskID );
748:
}
749:
break;
750:
751:
case ATT_EXCHANGE_MTU_RSP:
752:
stat = ATT_ParseExchangeMTURsp( &pBuf[2], pCmd->len-2, &msg );
753:
if ( stat == SUCCESS )
754:
{
755:
stat = ATT_ExchangeMTURsp( connHandle, &msg.exchangeMTURsp );
756:
}
757:
break;
758:
759:
case ATT_FIND_INFO_REQ:
760:
stat = ATT_ParseFindInfoReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
761:
if ( stat == SUCCESS )
762:
{
763:
stat = GATT_DiscAllCharDescs( connHandle, msg.findInfoReq.startHandle,
764:
msg.findInfoReq.endHandle,
hciExtApp_TaskID );
765:
}
766:
break;
767:
768:
case ATT_FIND_INFO_RSP:
769:
stat = ATT_ParseFindInfoRsp( &pBuf[2], pCmd->len-2, &msg );
770:
if ( stat == SUCCESS )
771:
{
772:
stat = ATT_FindInfoRsp( connHandle, &msg.findInfoRsp );

13/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

773:
774:
775:
776:
777:
778:
779:
780:
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792:
793:
794:
795:
796:
797:
798:
799:
800:
801:
802:
803:
804:
805:
806:
807:

}
break;
case ATT_FIND_BY_TYPE_VALUE_REQ:
stat = ATT_ParseFindByTypeValueReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
attFindByTypeValueReq_t *pReq = &msg.findByTypeValueReq;
// Find out what's been requested
&&
if ( gattPrimaryServiceType( pReq->type )
( pReq->startHandle == GATT_MIN_HANDLE ) &&
( pReq->endHandle
== GATT_MAX_HANDLE ) )
{
// Discover primary service by service UUID
stat = GATT_DiscPrimaryServiceByUUID( connHandle, pReq->value,
pReq->len, hciExtApp_TaskID );
}
else
{
stat = INVALIDPARAMETER;
}
}
break;
case ATT_FIND_BY_TYPE_VALUE_RSP:
stat = ATT_ParseFindByTypeValueRsp( &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = ATT_FindByTypeValueRsp( connHandle, &msg.findByTypeValueRsp );
}
break;

case ATT_READ_BY_TYPE_REQ:
stat = ATT_ParseReadByTypeReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
808:
if ( stat == SUCCESS )
809:
{
810:
attReadByTypeReq_t *pReq = &msg.readByTypeReq;
811:
812:
// Find out what's been requested
813:
if ( gattIncludeType( pReq->type ) )
814:
{
815:
// Find included services
816:
stat = GATT_FindIncludedServices( connHandle, pReq->startHandle,
817:
pReq->endHandle, hciExtApp_TaskID );
818:
}
819:
else if ( gattCharacterType( pReq->type ) )
820:
{
821:
// Discover all characteristics of a service
822:
stat = GATT_DiscAllChars( connHandle, pReq->startHandle,
823:
pReq->endHandle, hciExtApp_TaskID );
824:
}
825:
else
826:
{
827:
// Read using characteristic UUID
828:
stat = GATT_ReadUsingCharUUID( connHandle, pReq, hciExtApp_TaskID );
829:
}
830:
}
831:
break;
832:

14/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

833:
834:
835:
836:
837:
838:
839:
840:
841:
842:

case ATT_READ_BY_TYPE_RSP:
stat = ATT_ParseReadByTypeRsp( &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = ATT_ReadByTypeRsp( connHandle, &msg.readByTypeRsp );
}
break;

case ATT_READ_REQ:
stat = ATT_ParseReadReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd->len2, &msg );
843:
if ( stat == SUCCESS )
844:
{
845:
// Read Characteristic Value or Read Characteristic Descriptor
846:
stat = GATT_ReadCharValue( connHandle, &msg.readReq, hciExtApp_TaskID );
847:
}
848:
break;
849:
850:
case ATT_READ_RSP:
851:
stat = ATT_ParseReadRsp( &pBuf[2], pCmd->len-2, &msg );
852:
if ( stat == SUCCESS )
853:
{
854:
stat = ATT_ReadRsp( connHandle, &msg.readRsp );
855:
}
856:
break;
857:
858:
case ATT_READ_BLOB_REQ:
859:
stat = ATT_ParseReadBlobReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
860:
if ( stat == SUCCESS )
861:
{
862:
// Read long characteristic value
863:
stat = GATT_ReadLongCharValue( connHandle, &msg.readBlobReq,
hciExtApp_TaskID );
864:
}
865:
break;
866:
867:
case ATT_READ_BLOB_RSP:
868:
stat = ATT_ParseReadBlobRsp( &pBuf[2], pCmd->len-2, &msg );
869:
if ( stat == SUCCESS )
870:
{
871:
stat = ATT_ReadBlobRsp( connHandle, &msg.readBlobRsp );
872:
}
873:
break;
874:
875:
case ATT_READ_MULTI_REQ:
876:
stat = ATT_ParseReadMultiReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
877:
if ( stat == SUCCESS )
878:
{
879:
stat = GATT_ReadMultiCharValues( connHandle, &msg.readMultiReq,
hciExtApp_TaskID );
880:
}
881:
break;
882:
883:
case ATT_READ_MULTI_RSP:
884:
stat = ATT_ParseReadMultiRsp( &pBuf[2], pCmd->len-2, &msg );
885:
if ( stat == SUCCESS )
886:
{
887:
stat = ATT_ReadMultiRsp( connHandle, &msg.readMultiRsp );
888:
}
889:
break;

15/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

890:
891:
892:

case ATT_READ_BY_GRP_TYPE_REQ:
stat = ATT_ParseReadByTypeReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
893:
if ( stat == SUCCESS )
894:
{
895:
attReadByGrpTypeReq_t *pReq = &msg.readByGrpTypeReq;
896:
897:
// Find out what's been requested
898:
&&
if ( gattPrimaryServiceType( pReq->type )
899:
( pReq->startHandle == GATT_MIN_HANDLE ) &&
900:
( pReq->endHandle
== GATT_MAX_HANDLE ) )
901:
{
902:
// Discover all primary services
903:
stat = GATT_DiscAllPrimaryServices( connHandle, hciExtApp_TaskID );
904:
}
905:
else
906:
{
907:
stat = INVALIDPARAMETER;
908:
}
909:
}
910:
break;
911:
912:
case ATT_READ_BY_GRP_TYPE_RSP:
913:
stat = ATT_ParseReadByGrpTypeRsp( &pBuf[2], pCmd->len-2, &msg );
914:
if ( stat == SUCCESS )
915:
{
916:
stat = ATT_ReadByGrpTypeRsp( connHandle, &msg.readByGrpTypeRsp );
917:
}
918:
break;
919:
920:
case ATT_WRITE_REQ:
921:
stat = ATT_ParseWriteReq( pBuf[2], pBuf[3], &pBuf[4], pCmd->len-4, &msg );
922:
if ( stat == SUCCESS )
923:
{
924:
attWriteReq_t *pReq = &msg.writeReq;
925:
926:
if ( pReq->cmd == FALSE )
927:
{
928:
// Write Characteristic Value or Write Characteristic Descriptor
929:
stat = GATT_WriteCharValue( connHandle, &msg.writeReq,
hciExtApp_TaskID );
930:
}
931:
else
932:
{
933:
if ( pReq->sig == FALSE )
934:
{
935:
// Write Without Response
936:
stat = GATT_WriteNoRsp( connHandle, pReq );
937:
}
938:
else
939:
{
940:
// Signed Write Without Response
941:
stat = GATT_SignedWriteNoRsp( connHandle, pReq );
942:
}
943:
}
944:
}
945:
break;
946:
947:
case ATT_WRITE_RSP:
948:
stat = ATT_ParseWriteRsp( &pBuf[2], pCmd->len-2, &msg );
949:
if ( stat == SUCCESS )

16/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

950:
951:
952:
953:
954:
955:
956:
957:
958:
959:
960:
961:
962:
963:
964:
965:
966:
967:
968:
969:
970:
971:
972:
973:
974:
975:
976:
977:
978:
979:
980:
981:
982:
983:
984:
985:
986:
987:
988:
989:
990:
991:
992:
993:
994:
995:
996:
997:
998:
999:
1000:
1001:
1002:
1003:
1004:

{
stat = ATT_WriteRsp( connHandle );
}
break;
case ATT_PREPARE_WRITE_REQ:
stat = ATT_ParsePrepareWriteReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
#if !defined ( GATT_DB_OFF_CHIP ) && defined ( TESTMODES )
if ( GATTServApp_GetParamValue() == GATT_TESTMODE_PREPARE_WRITE )
{
// Send the Prepare Write Request right away - needed for GATT testing
stat = GATT_PrepareWriteReq( connHandle, &msg.prepareWriteReq,
hciExtApp_TaskID );
}
else
#endif // !GATT_DB_OFF_CHIP && TESTMODE
{
// GATT Reliable Writes
if ( pPrepareWrites == NULL )
{
// First allocated buffer for the Prepare Write Requests
pPrepareWrites = osal_mem_alloc( GATT_MAX_NUM_RELIABLE_WRITES *
sizeof( attPrepareWriteReq_t ) );
}
if ( pPrepareWrites != NULL )
{
if ( numPrepareWrites < GATT_MAX_NUM_RELIABLE_WRITES )
{
// Save the Prepare Write Request for now
pPrepareWrites[numPrepareWrites++] = msg.prepareWriteReq;
}
else
{
stat = INVALIDPARAMETER;
}
}
else
{
stat = bleMemAllocError;
}
}
}
break;
case ATT_PREPARE_WRITE_RSP:
stat = ATT_ParsePrepareWriteRsp( &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = ATT_PrepareWriteRsp( connHandle, &msg.prepareWriteRsp );
}
break;

case ATT_EXECUTE_WRITE_REQ:
stat = ATT_ParseExecuteWriteReq( ATT_SIG_NOT_INCLUDED, TRUE, &pBuf[2],
pCmd->len-2, &msg );
1005:
if ( stat == SUCCESS )
1006:
{
1007: #if !defined ( GATT_DB_OFF_CHIP ) && defined ( TESTMODES )

17/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1008:
1009:
1010:
1011:
1012:
1013:
1014:
1015:
1016:
1017:
1018:
1019:
1020:
1021:
1022:
1023:
1024:
1025:
1026:
1027:
1028:
1029:
1030:
1031:
1032:
1033:
1034:
1035:
1036:
1037:
1038:
1039:
1040:
1041:
1042:
1043:
1044:
1045:
1046:
1047:
1048:
1049:
1050:
1051:
1052:
1053:
1054:
1055:
1056:
1057:
1058:
1059:
1060:
1061:
1062:
1063:

if ( GATTServApp_GetParamValue() == GATT_TESTMODE_PREPARE_WRITE )
{
// Send the Execute Write Request right away - needed for GATT testing
stat = GATT_ExecuteWriteReq( connHandle, &msg.executeWriteReq,
hciExtApp_TaskID );
}
else
#endif // !GATT_DB_OFF_CHIP && TESTMODE
if ( pPrepareWrites != NULL )
{
// GATT Reliable Writes - send all saved Prepare Write Requests
stat = GATT_ReliableWrites( connHandle, pPrepareWrites,
numPrepareWrites,
msg.executeWriteReq.flags,
hciExtApp_TaskID );
if ( stat != SUCCESS )
{
osal_mem_free( pPrepareWrites );
}
// else pPrepareWrites will be freed by GATT Client
// Reset GATT Reliable Writes variables
pPrepareWrites = NULL;
numPrepareWrites = 0;
}
else
{
stat = INVALIDPARAMETER;
}
}
break;
case ATT_EXECUTE_WRITE_RSP:
stat = ATT_ParseExecuteWriteRsp( &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = ATT_ExecuteWriteRsp( connHandle );
}
break;
case ATT_HANDLE_VALUE_NOTI:
stat = ATT_ParseHandleValueInd( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[3],
pCmd->len-3, &msg );
if ( stat == SUCCESS )
{
stat = GATT_Notification( connHandle, &msg.handleValueNoti, pBuf[2] );
}
break;
case ATT_HANDLE_VALUE_IND:
stat = ATT_ParseHandleValueInd( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[3],
pCmd->len-3, &msg );
if ( stat == SUCCESS )
{
stat = GATT_Indication( connHandle, &msg.handleValueInd, pBuf[2],
hciExtApp_TaskID );
}
break;
case ATT_HANDLE_VALUE_CFM:
stat = ATT_ParseHandleValueCfm( &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )

18/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1064:
{
1065:
stat = ATT_HandleValueCfm( connHandle );
1066:
}
1067:
break;
1068:
1069:
default:
1070:
stat = FAILURE;
1071:
break;
1072:
}
1073:
1074:
return ( mapATT2BLEStatus( stat ) );
1075: }
1076:
1077: /*********************************************************************
1078: * @fn
processExMsgGATT
1079: *
1080: * @brief
Parse and process incoming HCI extension GATT messages.
1081: *
1082: * @param
cmdID - incoming HCI extension command ID.
1083: * @param
pCmd - incoming HCI extension message.
1084: * @param
pRspDataLen - response data length to be returned.
1085: *
1086: * @return SUCCESS, INVALIDPARAMETER, FAILURE,
1087: *
bleInvalidPDU or bleMemAllocError
1088: */
1089: static uint8 processExMsgGATT( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen )
1090: {
1091: #ifdef GATT_DB_OFF_CHIP
1092:
static uint16 totalAttrs = 0;
1093:
static gattService_t service = { 0, NULL };
1094: #endif
1095:
uint8 *pBuf = pCmd->pData;
1096:
uint16 connHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
1097:
attMsg_t msg;
1098:
bStatus_t stat = SUCCESS;
1099:
1100:
switch( cmdID )
1101:
{
1102:
case ATT_EXCHANGE_MTU_REQ: // GATT Exchange MTU
1103:
stat = ATT_ParseExchangeMTUReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
1104:
if ( stat == SUCCESS )
1105:
{
1106:
stat = GATT_ExchangeMTU( connHandle, &msg.exchangeMTUReq,
hciExtApp_TaskID );
1107:
}
1108:
break;
1109:
1110:
case ATT_READ_BY_GRP_TYPE_REQ: // GATT Discover All Primary Services
1111:
stat = GATT_DiscAllPrimaryServices( connHandle, hciExtApp_TaskID );
1112:
break;
1113:
1114:
case ATT_FIND_BY_TYPE_VALUE_REQ: // GATT Discover Primary Service By UUID
1115:
stat = GATT_DiscPrimaryServiceByUUID( connHandle, &pBuf[2],
1116:
pCmd->len-2, hciExtApp_TaskID );
1117:
break;
1118:
1119:
case GATT_FIND_INCLUDED_SERVICES: // GATT Find Included Services
1120:
case GATT_DISC_ALL_CHARS: // GATT Discover All Characteristics
1121:
if ( ( pCmd->len-2 ) == READ_BY_TYPE_REQ_FIXED_SIZE )
1122:
{

19/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1123:
1124:
1125:
1126:
1127:
1128:
1129:
1130:
1131:
1132:
1133:
1134:
1135:
1136:
1137:
1138:
1139:
1140:
1141:
1142:
1143:
1144:
1145:
1146:
1147:
1148:
1149:
1150:
1151:
1152:
1153:
1154:
1155:
1156:
1157:
1158:
1159:
1160:
1161:
1162:
1163:
1164:

// First requested handle number


uint16 startHandle = BUILD_UINT16( pBuf[2], pBuf[3] );
// Last requested handle number
uint16 endHandle = BUILD_UINT16( pBuf[4], pBuf[5] );
if ( cmdID == GATT_FIND_INCLUDED_SERVICES )
{
stat = GATT_FindIncludedServices( connHandle, startHandle,
endHandle, hciExtApp_TaskID );
}
else
{
stat = GATT_DiscAllChars( connHandle, startHandle,
endHandle, hciExtApp_TaskID );
}
}
else
{
stat = ATT_ERR_INVALID_PDU;
}
break;
case ATT_READ_BY_TYPE_REQ: // GATT Discover Characteristics by UUID
stat = ATT_ParseReadByTypeReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_DiscCharsByUUID( connHandle, &msg.readByTypeReq,
hciExtApp_TaskID );
}
break;
case ATT_FIND_INFO_REQ: // GATT Discover All Characteristic Descriptors
stat = ATT_ParseFindInfoReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_DiscAllCharDescs( connHandle, msg.findInfoReq.startHandle,
msg.findInfoReq.endHandle,
hciExtApp_TaskID );
}
break;

case ATT_READ_REQ: // GATT Read Characteristic Value


stat = ATT_ParseReadReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd->len2, &msg );
1165:
if ( stat == SUCCESS )
1166:
{
1167:
stat = GATT_ReadCharValue( connHandle, &msg.readReq, hciExtApp_TaskID );
1168:
}
1169:
break;
1170:
1171:
case GATT_READ_USING_CHAR_UUID: // GATT Read Using Characteristic UUID
1172:
stat = ATT_ParseReadByTypeReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2],
pCmd->len-2, &msg );
1173:
if ( stat == SUCCESS )
1174:
{
1175:
stat = GATT_ReadUsingCharUUID( connHandle, &msg.readByTypeReq,
hciExtApp_TaskID );
1176:
}
1177:
break;

20/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185:
1186:
1187:
1188:
1189:
1190:
1191:
1192:
1193:
1194:
1195:
1196:
1197:
1198:
1199:
1200:
1201:
1202:
1203:
1204:
1205:
1206:
1207:
1208:
1209:
1210:
1211:
1212:
1213:
1214:
1215:

case ATT_READ_BLOB_REQ: // GATT Read Long Characteristic Value


stat = ATT_ParseReadBlobReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_ReadLongCharValue( connHandle, &msg.readBlobReq,
hciExtApp_TaskID );
}
break;
case ATT_READ_MULTI_REQ: // GATT Read Multiple Characteristic Values
stat = ATT_ParseReadMultiReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_ReadMultiCharValues( connHandle, &msg.readMultiReq,
hciExtApp_TaskID );
}
break;
case GATT_WRITE_NO_RSP: // GATT Write Without Response
stat = ATT_ParseWriteReq( FALSE, TRUE, &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_WriteNoRsp( connHandle, &msg.writeReq );
}
break;
case GATT_SIGNED_WRITE_NO_RSP: // GATT Signed Write Without Response
stat = ATT_ParseWriteReq( TRUE, TRUE, &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_SignedWriteNoRsp( connHandle, &msg.writeReq );
}
break;
case ATT_WRITE_REQ: // GATT Write Characteristic Value
stat = ATT_ParseWriteReq( FALSE, FALSE, &pBuf[2], pCmd->len-2, &msg );
if ( stat == SUCCESS )
{
stat = GATT_WriteCharValue( connHandle, &msg.writeReq, hciExtApp_TaskID
);

1216:
1217:
1218:
1219:
1220:
1221:
1222:
1223:
1224:
1225:
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:

}
break;
case
case
//
if
{

ATT_PREPARE_WRITE_REQ: // GATT Write Long Characteristic Value


GATT_WRITE_LONG_CHAR_DESC: // GATT Write Long Characteristic Descriptor
Make sure there's an attribute value to be written
( pCmd->len-2 > PREPARE_WRITE_REQ_FIXED_SIZE )
gattPrepareWriteReq_t req; // GATT Request
// Value length
req.len = pCmd->len - (2 + PREPARE_WRITE_REQ_FIXED_SIZE);
// Allocate buffer for the attribute value
if ( req.pValue = osal_mem_alloc( req.len ) )
{
// Attribute handle
req.handle = BUILD_UINT16( pBuf[2], pBuf[3] );

21/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:

// Value offset
req.offset = BUILD_UINT16( pBuf[4], pBuf[5] );
// Attribute value
VOID osal_memcpy( req.pValue, &(pBuf[6]), req.len );
if ( cmdID == ATT_PREPARE_WRITE_REQ )
{
stat = GATT_WriteLongCharValue( connHandle, &req, hciExtApp_TaskID
);

1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253:
1254:
1255:
1256:
1257:
1258:
1259:
1260:
1261:
1262:
1263:
1264:
1265:
1266:
1267:
1268:
1269:
1270:
1271:
1272:
1273:
1274:
1275:

}
else
{
stat = GATT_WriteLongCharDesc( connHandle, &req, hciExtApp_TaskID );
}
if ( stat != SUCCESS )
{
osal_mem_free( req.pValue );
}
// else req.pValue will be freed by GATT Client
}
else
{
stat = bleMemAllocError;
}
}
else
{
stat = ATT_ERR_INVALID_PDU;
}
break;
case GATT_RELIABLE_WRITES: // GATT Reliable Writes
if ( pCmd->len-2 > 0 )
{
uint8 numReqs = pBuf[2];

if ( ( numReqs > 0 ) && ( numReqs <= GATT_MAX_NUM_RELIABLE_WRITES ) )


{
// First allocated buffer for the Prepare Write Requests
attPrepareWriteReq_t *pReqs = osal_mem_alloc( numReqs * sizeof(
attPrepareWriteReq_t ) );
1276:
if ( pReqs != NULL )
1277:
{
1278:
pBuf += 3; // pass connHandle and numReqs
1279:
1280:
for ( uint8 i = 0; i < numReqs; i++ )
1281:
{
1282:
// length of request is length of attribute value plus fixed
fields
1283:
uint8 reqLen = PREPARE_WRITE_REQ_FIXED_SIZE + *pBuf++;
1284:
1285:
stat = ATT_ParsePrepareWriteReq( ATT_SIG_NOT_INCLUDED, FALSE,
pBuf,
1286:
reqLen, (attMsg_t *)&(pReqs[i])
);
1287:
if ( stat != SUCCESS )
1288:
{
1289:
break;
1290:
}
1291:

22/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1292:
1293:
1294:
1295:
1296:
1297:
1298:
1299:
1300:
1301:
1302:
1303:
1304:
1305:
1306:
1307:
1308:
1309:
1310:
1311:
1312:
1313:
1314:
1315:
1316:
1317:
1318:
1319:
1320:
1321:
1322:
1323:
1324:
1325:

// Next request
pBuf += reqLen;
}
if ( stat == SUCCESS )
{
// Send all saved Prepare Write Requests
stat = GATT_ReliableWrites( connHandle, pReqs, numReqs,
ATT_WRITE_PREPARED_VALUES,
hciExtApp_TaskID );
if ( stat != SUCCESS )
{
osal_mem_free( pReqs );
}
// else pReqs will be freed by GATT Client
}
}
else
{
stat = bleMemAllocError;
}
}
else
{
stat = INVALIDPARAMETER;
}
}
else
{
stat = ATT_ERR_INVALID_PDU;
}
break;

case GATT_READ_CHAR_DESC: // GATT Read Characteristic Descriptor


stat = ATT_ParseReadReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd->len2, &msg );
1326:
if ( stat == SUCCESS )
1327:
{
1328:
stat = GATT_ReadCharDesc( connHandle, &msg.readReq, hciExtApp_TaskID );
1329:
}
1330:
break;
1331:
1332:
case GATT_READ_LONG_CHAR_DESC: // GATT Read Long Characteristic Descriptor
1333:
stat = ATT_ParseReadBlobReq( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[2], pCmd>len-2, &msg );
1334:
if ( stat == SUCCESS )
1335:
{
1336:
stat = GATT_ReadLongCharDesc( connHandle, &msg.readBlobReq,
hciExtApp_TaskID );
1337:
}
1338:
break;
1339:
1340:
case GATT_WRITE_CHAR_DESC: // GATT Write Characteristic Descriptor
1341:
stat = ATT_ParseWriteReq( FALSE, FALSE, &pBuf[2], pCmd->len-2, &msg );
1342:
if ( stat == SUCCESS )
1343:
{
1344:
stat = GATT_WriteCharDesc( connHandle, &msg.writeReq, hciExtApp_TaskID
);
1345:
}
1346:
break;
1347:
1348:
case ATT_HANDLE_VALUE_NOTI:

23/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1349:
1350:
1351:
1352:
1353:
1354:
1355:
1356:
1357:
1358:
1359:
1360:

stat = ATT_ParseHandleValueInd( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[3],


pCmd->len-3, &msg );
if ( stat == SUCCESS )
{
stat = GATT_Notification( connHandle, &msg.handleValueNoti, pBuf[2] );
}
break;
case ATT_HANDLE_VALUE_IND:
stat = ATT_ParseHandleValueInd( ATT_SIG_NOT_INCLUDED, FALSE, &pBuf[3],
pCmd->len-3, &msg );
if ( stat == SUCCESS )
{
stat = GATT_Indication( connHandle, &msg.handleValueInd, pBuf[2],
hciExtApp_TaskID );
}
break;

1361:
1362:
1363:
1364: #ifdef GATT_DB_OFF_CHIP // These GATT commands don't include connHandle field
1365:
case HCI_EXT_GATT_ADD_SERVICE:
1366:
if ( service.attrs == NULL )
1367:
{
1368:
// Service type must be 2 octets (Primary or Secondary)
1369:
if ( pCmd->len-2 == ATT_BT_UUID_SIZE )
1370:
{
1371:
uint16 uuid = BUILD_UINT16( pBuf[0], pBuf[1] );
1372:
uint16 numAttrs = BUILD_UINT16( pBuf[2], pBuf[3] );
1373:
1374:
||
if ( ( ( uuid == GATT_PRIMARY_SERVICE_UUID )
1375:
( uuid == GATT_SECONDARY_SERVICE_UUID ) ) &&
1376:
( numAttrs > 0 ) )
1377:
{
1378:
// Allocate buffer for the attribute table
1379:
service.attrs = osal_mem_alloc( numAttrs * sizeof( gattAttribute_t
) );
1380:
if ( service.attrs != NULL )
1381:
{
1382:
// Zero out all attribute fields
1383:
VOID osal_memset( service.attrs, 0, numAttrs * sizeof(
gattAttribute_t ) );
1384:
1385:
totalAttrs = numAttrs;
1386:
1387:
// Set up service record
1388:
stat = addAttrRec( &service, pBuf, ATT_BT_UUID_SIZE,
1389:
GATT_PERMIT_READ, &totalAttrs, pRspDataLen );
1390:
}
1391:
else
1392:
{
1393:
stat = bleMemAllocError;
1394:
}
1395:
}
1396:
else
1397:
{
1398:
stat = INVALIDPARAMETER;
1399:
}
1400:
}
1401:
else
1402:
{
1403:
stat = ATT_ERR_INVALID_PDU;
1404:
}
1405:
}

24/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1406:
else
1407:
{
1408:
stat = blePending;
1409:
}
1410:
break;
1411:
1412:
case HCI_EXT_GATT_DEL_SERVICE:
1413:
{
1414:
uint16 handle = BUILD_UINT16( pBuf[0], pBuf[1] );
1415:
1416:
if ( handle == 0x0000 )
1417:
{
1418:
// Service is not registered with GATT yet
1419:
freeAttrRecs( &service );
1420:
1421:
totalAttrs = 0;
1422:
}
1423:
else
1424:
{
1425:
gattService_t serv;
1426:
1427:
// Service is already registered with the GATT Server
1428:
stat = GATT_DeregisterService( handle, &serv );
1429:
if ( stat == SUCCESS )
1430:
{
1431:
freeAttrRecs( &serv );
1432:
}
1433:
}
1434:
}
1435:
break;
1436:
1437:
case HCI_EXT_GATT_ADD_ATTRIBUTE:
1438:
if ( service.attrs != NULL )
1439:
{
1440:
if ( ( pCmd->len-1 == ATT_UUID_SIZE ) ||
1441:
( pCmd->len-1 == ATT_BT_UUID_SIZE ) )
1442:
{
1443:
// Add attribute record to the service being added
1444:
stat = addAttrRec( &service, pBuf, pCmd->len-1,
1445:
pBuf[pCmd->len-1], &totalAttrs, pRspDataLen );
1446:
}
1447:
else
1448:
{
1449:
stat = ATT_ERR_INVALID_PDU;
1450:
}
1451:
}
1452:
else // no corresponding service
1453:
{
1454:
stat = INVALIDPARAMETER;
1455:
}
1456:
break;
1457: #endif // GATT_DB_OFF_CHIP
1458:
1459:
default:
1460:
stat = FAILURE;
1461:
break;
1462:
}
1463:
1464:
return ( mapATT2BLEStatus( stat ) );
1465: }
1466:
1467: /*********************************************************************

25/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1468: * @fn
processExMsgGAP
1469: *
1470: * @brief
Parse and process incoming HCI extension GAP messages.
1471: *
1472: * @param
cmdID - incoming HCI extension command ID.
1473: * @param
pCmd - incoming HCI extension message.
1474: * @param
pRspDataLen - response data length to be returned.
1475: *
1476: * @return SUCCESS, INVALIDPARAMETER, FAILURE,
1477: *
or bleMemAllocError
1478: */
1479: static uint8 processExMsgGAP( uint8 cmdID, hciExtCmd_t *pCmd, uint8
*pRspDataLen )
1480: {
1481:
uint8 *pBuf = pCmd->pData;
1482:
bStatus_t stat = SUCCESS;
1483:
1484:
switch( cmdID )
1485:
{
1486:
case HCI_EXT_GAP_DEVICE_INIT:
1487:
{
1488:
uint32 signCounter;
1489:
uint8 profileRole = pBuf[0];
1490:
1491: #if defined ( GAP_BOND_MGR )
1492:
hciExtProfileRole = profileRole;
1493: #endif
1494:
1495:
// Copy the IRK, SRK and sign counter from the command if they aren't
all "0",
1496:
// otherwise use what's in NV
1497:
if ( osal_isbufset( &pBuf[2], 0, KEYLEN ) == FALSE )
1498:
{
1499:
VOID osal_memcpy( IRK, &pBuf[2], KEYLEN );
1500:
}
1501:
1502:
if ( osal_isbufset( &pBuf[2+KEYLEN], 0, KEYLEN ) == FALSE )
1503:
{
1504:
VOID osal_memcpy( SRK, &pBuf[2+KEYLEN], KEYLEN );
1505:
}
1506:
1507:
signCounter = BUILD_UINT32( pBuf[2+KEYLEN+KEYLEN+0],
pBuf[2+KEYLEN+KEYLEN+1],
1508:
pBuf[2+KEYLEN+KEYLEN+2],
pBuf[2+KEYLEN+KEYLEN+3] );
1509:
if ( signCounter > 0 )
1510:
{
1511:
hciExtSignCounter = signCounter;
1512:
}
1513:
1514:
stat = GAP_DeviceInit( hciExtApp_TaskID, profileRole, pBuf[1], IRK, SRK,
&hciExtSignCounter );
1515:
HCI_EXT_SetRxGainCmd(HCI_EXT_RX_GAIN_HIGH);
1516:
1517:
// Take over the processing of Authentication messages
1518:
VOID GAP_SetParamValue( TGAP_AUTH_TASK_ID, hciExtApp_TaskID );
1519:
}
1520:
break;
1521:
1522:
case HCI_EXT_GAP_CONFIG_DEVICE_ADDR:
1523:
{
1524:
uint8 *pStaticAddr = NULL;

26/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1525:
uint8 nullAddr[B_ADDR_LEN] = {0};
1526:
1527:
if ( osal_memcmp( &pBuf[1], nullAddr, B_ADDR_LEN ) != TRUE )
1528:
{
1529:
pStaticAddr = &pBuf[1];
1530:
}
1531:
1532:
stat = GAP_ConfigDeviceAddr( pBuf[0], pStaticAddr );
1533:
}
1534:
break;
1535:
1536: #if ( HOST_CONFIG & ( CENTRAL_CFG | OBSERVER_CFG ) )
1537:
case HCI_EXT_GAP_DEVICE_DISC_REQ:
1538:
{
1539:
gapDevDiscReq_t discReq;
1540:
1541:
discReq.taskID = hciExtApp_TaskID;
1542:
discReq.mode = *pBuf++;
1543:
discReq.activeScan = *pBuf++;
1544:
discReq.whiteList = *pBuf;
1545:
1546:
stat = GAP_DeviceDiscoveryRequest( &discReq );
1547:
}
1548:
break;
1549:
1550:
case HCI_EXT_GAP_DEVICE_DISC_CANCEL:
1551:
stat = GAP_DeviceDiscoveryCancel( hciExtApp_TaskID );
1552:
break;
1553: #endif // OBSERVER_CFG | CENTRAL_CFG
1554:
1555: #if ( HOST_CONFIG & CENTRAL_CFG )
1556:
case HCI_EXT_GAP_EST_LINK_REQ:
1557:
{
1558:
gapEstLinkReq_t linkReq;
1559:
1560:
linkReq.taskID = hciExtApp_TaskID;
1561:
linkReq.highDutyCycle = *pBuf++;
1562:
linkReq.whiteList = *pBuf++;
1563:
linkReq.addrTypePeer = *pBuf++;
1564:
VOID osal_memcpy( linkReq.peerAddr, pBuf, B_ADDR_LEN );
1565:
1566:
stat = GAP_EstablishLinkReq( &linkReq );
1567:
}
1568:
break;
1569:
1570:
case HCI_EXT_GAP_UPDATE_LINK_PARAM_REQ:
1571:
{
1572:
gapUpdateLinkParamReq_t updateLinkReq;
1573:
1574:
updateLinkReq.connectionHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
1575:
pBuf += 2;
1576:
updateLinkReq.intervalMin = BUILD_UINT16( pBuf[0], pBuf[1] );
1577:
pBuf += 2;
1578:
updateLinkReq.intervalMax = BUILD_UINT16( pBuf[0], pBuf[1] );
1579:
pBuf += 2;
1580:
updateLinkReq.connLatency = BUILD_UINT16( pBuf[0], pBuf[1] );
1581:
pBuf += 2;
1582:
updateLinkReq.connTimeout = BUILD_UINT16( pBuf[0], pBuf[1] );
1583:
1584:
stat = GAP_UpdateLinkParamReq( &updateLinkReq );
1585:
}
1586:
break;

27/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1587: #endif // CENTRAL_CFG


1588:
1589:
case HCI_EXT_GAP_TERMINATE_LINK:
1590:
stat = GAP_TerminateLinkReq( hciExtApp_TaskID, BUILD_UINT16( pBuf[0],
pBuf[1] ) );
1591:
break;
1592:
1593: #if ( HOST_CONFIG & ( PERIPHERAL_CFG | BROADCASTER_CFG ) )
1594:
case HCI_EXT_GAP_MAKE_DISCOVERABLE:
1595:
{
1596:
gapAdvertisingParams_t adParams;
1597:
1598:
adParams.eventType = *pBuf++;
1599:
adParams.initiatorAddrType = *pBuf++;
1600:
VOID osal_memcpy( adParams.initiatorAddr, pBuf, B_ADDR_LEN );
1601:
pBuf += B_ADDR_LEN;
1602:
adParams.channelMap = *pBuf++;
1603:
adParams.filterPolicy = *pBuf;
1604:
stat = GAP_MakeDiscoverable( hciExtApp_TaskID, &adParams );
1605:
}
1606:
break;
1607:
1608:
case HCI_EXT_GAP_UPDATE_ADV_DATA:
1609:
stat = GAP_UpdateAdvertisingData( hciExtApp_TaskID, pBuf[0], pBuf[1],
&pBuf[2] );
1610:
break;
1611:
1612:
case HCI_EXT_GAP_END_DISC:
1613:
stat = GAP_EndDiscoverable( hciExtApp_TaskID );
1614:
break;
1615: #endif // PERIPHERAL_CFG | BROADCASTER_CFG
1616:
1617:
case HCI_EXT_GAP_AUTHENTICATE:
1618:
{
1619:
uint8 tmp;
1620:
gapAuthParams_t params;
1621:
gapPairingReq_t pairReq;
1622:
gapPairingReq_t *pPairReq = NULL;
1623:
1624: #if ( OSALMEM_METRICS )
1625:
uint16 memUsed = osal_heap_mem_used();
1626: #endif
1627:
1628:
VOID osal_memset( &params, 0, sizeof ( gapAuthParams_t ) );
1629:
1630:
params.connectionHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
1631:
pBuf += 2;
1632:
1633:
params.secReqs.ioCaps = *pBuf++;
1634:
params.secReqs.oobAvailable = *pBuf++;
1635:
VOID osal_memcpy( params.secReqs.oob, pBuf, KEYLEN );
1636:
pBuf += KEYLEN;
1637:
params.secReqs.authReq = *pBuf++;
1638:
params.secReqs.maxEncKeySize = *pBuf++;
1639:
1640:
tmp = *pBuf++;
1641:
params.secReqs.keyDist.sEncKey = ( tmp & KEYDIST_SENC ) ? TRUE : FALSE;
1642:
params.secReqs.keyDist.sIdKey = ( tmp & KEYDIST_SID ) ? TRUE : FALSE;
1643:
params.secReqs.keyDist.sSign = ( tmp & KEYDIST_SSIGN ) ? TRUE : FALSE;
1644:
params.secReqs.keyDist.mEncKey = ( tmp & KEYDIST_MENC ) ? TRUE : FALSE;
1645:
params.secReqs.keyDist.mIdKey = ( tmp & KEYDIST_MID ) ? TRUE : FALSE;
1646:
params.secReqs.keyDist.mSign = ( tmp & KEYDIST_MSIGN ) ? TRUE : FALSE;

28/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1647:
params.secReqs.keyDist.reserved = 0;
1648:
1649:
tmp = *pBuf++;
1650:
if ( tmp )
1651:
{
1652:
pairReq.ioCap = *pBuf++;
1653:
pairReq.oobDataFlag = *pBuf++;
1654:
pairReq.authReq = *pBuf++;
1655:
pairReq.maxEncKeySize = *pBuf++;
1656:
tmp = *pBuf++;
1657:
pairReq.keyDist.sEncKey = ( tmp & KEYDIST_SENC ) ? TRUE : FALSE;
1658:
pairReq.keyDist.sIdKey = ( tmp & KEYDIST_SID ) ? TRUE : FALSE;
1659:
pairReq.keyDist.sSign = ( tmp & KEYDIST_SSIGN ) ? TRUE : FALSE;
1660:
pairReq.keyDist.mEncKey = ( tmp & KEYDIST_MENC ) ? TRUE : FALSE;
1661:
pairReq.keyDist.mIdKey = ( tmp & KEYDIST_MID ) ? TRUE : FALSE;
1662:
pairReq.keyDist.mSign = ( tmp & KEYDIST_MSIGN ) ? TRUE : FALSE;
1663:
pairReq.keyDist.reserved = 0;
1664:
pPairReq = &pairReq;
1665:
}
1666:
1667:
stat = GAP_Authenticate( &params, pPairReq );
1668:
1669: #if ( OSALMEM_METRICS )
1670:
*pRspDataLen = 2;
1671:
rspBuf[RSP_PAYLOAD_IDX] = LO_UINT16( memUsed );
1672:
rspBuf[RSP_PAYLOAD_IDX+1] = HI_UINT16( memUsed );
1673: #endif
1674:
}
1675:
break;
1676:
1677:
case HCI_EXT_GAP_TERMINATE_AUTH:
1678:
stat = GAP_TerminateAuth( BUILD_UINT16( pBuf[0], pBuf[1] ), pBuf[2] );
1679:
break;
1680:
1681:
case HCI_EXT_GAP_BOND:
1682:
{
1683:
uint16 connectionHandle;
1684:
smSecurityInfo_t securityInfo;
1685:
uint8 authenticated;
1686:
1687:
// Do Security Information part
1688:
connectionHandle = BUILD_UINT16( pBuf[0], pBuf[1] );
1689:
pBuf += 2;
1690:
authenticated = *pBuf++;
1691:
VOID osal_memcpy( securityInfo.ltk, pBuf, KEYLEN );
1692:
pBuf += KEYLEN;
1693:
securityInfo.div = BUILD_UINT16( pBuf[0], pBuf[1] );
1694:
pBuf += 2;
1695:
VOID osal_memcpy( securityInfo.rand, pBuf, B_RANDOM_NUM_SIZE );
1696:
pBuf += B_RANDOM_NUM_SIZE;
1697:
securityInfo.keySize = *pBuf++;
1698:
1699:
stat = GAP_Bond( connectionHandle, authenticated, &securityInfo, TRUE );
1700:
}
1701:
break;
1702:
1703:
case HCI_EXT_GAP_SIGNABLE:
1704:
{
1705:
uint16 connectionHandle;
1706:
uint8 authenticated;
1707:
smSigningInfo_t signing;
1708:

29/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1709:
1710:
1711:
1712:
1713:
1714:
1715:
1716:
1717:

connectionHandle = BUILD_UINT16( pBuf[0], pBuf[1] );


pBuf += 2;
authenticated = *pBuf++;
VOID osal_memcpy( signing.srk, pBuf, KEYLEN );
pBuf += KEYLEN;
signing.signCounter = BUILD_UINT32( pBuf[0], pBuf[1], pBuf[2], pBuf[3]
);

1718:
1719:
stat = GAP_Signable( connectionHandle, authenticated, &signing );
1720:
}
1721:
break;
1722:
1723:
case HCI_EXT_GAP_PASSKEY_UPDATE:
1724:
stat = GAP_PasskeyUpdate( &pBuf[2], BUILD_UINT16( pBuf[0], pBuf[1] ) );
1725:
break;
1726:
1727:
case HCI_EXT_GAP_SET_PARAM:
1728:
{
1729:
uint16 id = (uint16)pBuf[0];
1730:
uint16 value = BUILD_UINT16( pBuf[1], pBuf[2] );
1731:
1732:
if ( ( id != TGAP_AUTH_TASK_ID ) && ( id < TGAP_PARAMID_MAX ) )
1733:
{
1734:
stat = GAP_SetParamValue( id, value );
1735:
}
1736: #if !defined ( GATT_DB_OFF_CHIP ) && defined ( TESTMODES )
1737:
else if ( id == TGAP_GATT_TESTCODE )
1738:
{
1739:
GATTServApp_SetParamValue( value );
1740:
}
1741:
else if ( id == TGAP_ATT_TESTCODE )
1742:
{
1743:
ATT_SetParamValue( value );
1744:
}
1745:
else if ( id == TGAP_GGS_TESTCODE )
1746:
{
1747:
GGS_SetParamValue( value );
1748:
}
1749: #endif // !GATT_DB_OFF_CHIP && TESTMODES
1750:
else
1751:
{
1752:
stat = INVALIDPARAMETER;
1753:
}
1754:
}
1755:
break;
1756:
1757:
case HCI_EXT_GAP_GET_PARAM:
1758:
{
1759:
uint16 paramValue = 0xFFFF;
1760:
uint16 param = (uint16)pBuf[0];
1761:
1762:
if ( param < 0x00FF )
1763:
{
1764:
if ( ( param != TGAP_AUTH_TASK_ID ) && ( param < TGAP_PARAMID_MAX ) )
1765:
{
1766:
paramValue = GAP_GetParamValue( param );
1767:
}
1768: #if !defined ( GATT_DB_OFF_CHIP ) && defined ( TESTMODES )
1769:
else if ( param == TGAP_GATT_TESTCODE )

30/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1770:
1771:
1772:
1773:
1774:
1775:
1776:
1777:
1778:
1779:
1780:
1781:
1782:
1783:
1784:
1785:
1786:
1787:
1788:
1789:
1790:
1791:
1792:
1793:
1794:
1795:
1796:
1797:
1798:
1799:
1800:
1801:
1802:
1803:
1804:
1805:
1806:
1807:
1808:
1809:
1810:
1811:

{
paramValue = GATTServApp_GetParamValue();
}
else if ( param == TGAP_ATT_TESTCODE )
{
paramValue = ATT_GetParamValue();
}
else if ( param == TGAP_GGS_TESTCODE )
{
paramValue = GGS_GetParamValue();
}
#endif // !GATT_DB_OFF_CHIP && TESTMODES
}
#if ( OSALMEM_METRICS )
else
{
paramValue = osal_heap_mem_used();
}
#endif
if ( paramValue != 0xFFFF )
{
stat = SUCCESS;
}
else
{
stat = INVALIDPARAMETER;
}
*pRspDataLen = 2;
rspBuf[RSP_PAYLOAD_IDX] = LO_UINT16( paramValue );
rspBuf[RSP_PAYLOAD_IDX+1] = HI_UINT16( paramValue );
}
break;
case HCI_EXT_GAP_RESOLVE_PRIVATE_ADDR:
{
stat = GAP_ResolvePrivateAddr( &pBuf[0], &pBuf[KEYLEN] );
}
break;

#if ( HOST_CONFIG & PERIPHERAL_CFG )


case HCI_EXT_GAP_SLAVE_SECURITY_REQ_UPDATE:
stat = GAP_SendSlaveSecurityRequest( BUILD_UINT16( pBuf[0], pBuf[1] ),
pBuf[2] );
1812:
break;
1813: #endif // PERIPHERAL_CFG
1814:
1815: #if ( HOST_CONFIG & ( PERIPHERAL_CFG | BROADCASTER_CFG ) )
1816:
case HCI_EXT_GAP_SET_ADV_TOKEN:
1817:
{
1818:
gapAdvDataToken_t *pToken;
1819:
uint8 attrLen = pBuf[1];
1820:
1821:
pToken = (gapAdvDataToken_t *)osal_mem_alloc( sizeof (
gapAdvDataToken_t ) + attrLen );
1822:
if ( pToken )
1823:
{
1824:
pToken->adType = pBuf[0];
1825:
pToken->attrLen =attrLen;
1826:
pToken->pAttrData = (uint8 *)(pToken+1);
1827:
1828:
VOID osal_memcpy( pToken->pAttrData, &pBuf[2], attrLen );
1829:
stat = GAP_SetAdvToken( pToken );

31/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1830:
1831:
1832:
1833:
1834:
1835:
1836:
1837:
1838:
1839:
1840:
1841:
1842:
1843:
1844:
1845:
1846:
1847:
1848:
1849:
1850:
1851:
1852:
1853:
1854:
1855:
1856:
1857:
1858:
1859:
1860:
1861:
1862:
1863:
1864:
1865:
1866:
1867:
1868:
1869:
1870:
1871:
1872:
1873:
1874:
1875:
1876:
1877:
1878:
1879:
1880:
1881:
1882:
1883:
1884:
1885:
1886:
1887:
1888:
1889:
1890:
1891:

if ( stat != SUCCESS )
{
osal_mem_free( pToken );
}
}
else
{
stat = bleMemAllocError;
}
}
break;
case HCI_EXT_GAP_REMOVE_ADV_TOKEN:
{
gapAdvDataToken_t *pToken = GAP_RemoveAdvToken( pBuf[0] );
if ( pToken )
{
osal_mem_free( pToken );
stat = SUCCESS;
}
else
{
stat = INVALIDPARAMETER;
}
}
break;
case HCI_EXT_GAP_UPDATE_ADV_TOKENS:
{
stat = GAP_UpdateAdvTokens();
}
break;
#endif // PERIPHERAL_CFG | BROADCASTER_CFG
case HCI_EXT_GAP_BOND_SET_PARAM:
{
#if defined ( GAP_BOND_MGR )
uint16 id = BUILD_UINT16( pBuf[0], pBuf[1] );
uint8 *pValue;
uint32 passcode;
switch ( id )
{
case GAPBOND_DEFAULT_PASSCODE:
// First build passcode
passcode = osal_build_uint32( &pBuf[3], pBuf[2] );
pValue = (uint8 *)&passcode;
break;
default:
pValue = &pBuf[3];
break;
}
if ( stat == SUCCESS )
{
stat = GAPBondMgr_SetParameter( id, pBuf[2],
}

pValue );

#else
stat = INVALIDPARAMETER;
#endif
}

32/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1892:
1893:
1894:
1895:
1896:
1897:
1898:
1899:
1900:
1901:
1902:
1903:
1904:
1905:
1906:
1907:
1908:
1909:
1910:
1911:
1912:
1913:
1914:
1915:
1916:
1917:
1918:
1919:
1920:
1921:
1922:
1923:
1924:
1925:
1926:
1927:
1928:
1929:
1930:

break;
case HCI_EXT_GAP_BOND_GET_PARAM:
{
uint8 len = 0;
#if defined ( GAP_BOND_MGR )
uint16 id = BUILD_UINT16( pBuf[0], pBuf[1] );
stat = GAPBondMgr_GetParameter( id, &rspBuf[RSP_PAYLOAD_IDX] );
switch ( id )
{
case GAPBOND_INITIATE_WAIT:
len = 2;
break;
case GAPBOND_OOB_DATA:
len = KEYLEN;
break;
case GAPBOND_DEFAULT_PASSCODE:
len = 4;
break;
default:
len = 1;
break;
}
#else
stat = INVALIDPARAMETER;
#endif
*pRspDataLen = len;
}
break;
case HCI_EXT_GAP_BOND_SERVICE_CHANGE:
{
#if defined ( GAP_BOND_MGR )
stat = GAPBondMgr_ServiceChangeInd( BUILD_UINT16( pBuf[0], pBuf[1] ),
pBuf[2] );
#else
stat = INVALIDPARAMETER;
#endif
}
break;

1931:
1932:
1933:
1934:
1935:
1936:
1937:
default:
1938:
stat = FAILURE;
1939:
break;
1940:
}
1941:
1942:
return ( stat );
1943: }
1944:
1945: /*********************************************************************
1946: * @fn
processEvents
1947: *
1948: * @brief
Process an incoming Event messages.
1949: *
1950: * @param
pMsg - message to process
1951: *
1952: * @return none

33/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

1953: */
1954: static uint8 processEvents( osal_event_hdr_t *pMsg )
1955: {
1956:
uint8 msgLen = 0;
1957:
uint8 *pBuf = NULL;
1958:
uint8 allocated = FALSE;
1959:
uint8 deallocateIncoming;
1960:
1961:
VOID osal_memset( out_msg, 0, sizeof ( out_msg ) );
1962:
1963:
switch ( pMsg->event )
1964:
{
1965:
case GAP_MSG_EVENT:
1966:
pBuf = processEventsGAP( (gapEventHdr_t *)pMsg, out_msg, &msgLen,
&allocated );
1967:
break;
1968:
1969:
case L2CAP_SIGNAL_EVENT:
1970:
pBuf = processEventsL2CAP( (l2capSignalEvent_t *)pMsg, out_msg, &msgLen );
1971:
break;
1972:
1973:
case GATT_MSG_EVENT:
1974:
pBuf = processEventsGATT( (gattMsgEvent_t *)pMsg, out_msg, &msgLen,
&allocated );
1975:
break;
1976: #ifndef GATT_DB_OFF_CHIP
1977:
case GATT_SERV_MSG_EVENT:
1978:
pBuf = processEventsGATTServ( (gattEventHdr_t *)pMsg, out_msg, &msgLen );
1979:
break;
1980: #endif
1981:
default:
1982:
break; // ignore
1983:
}
1984:
1985:
// Deallocate here to free up heap space for the serial message set out HCI.
1986:
VOID osal_msg_deallocate( (uint8 *)pMsg );
1987:
deallocateIncoming = FALSE;
1988:
1989:
if ( msgLen )
1990:
{
1991:
HCI_SendControllerToHostEvent( HCI_VE_EVENT_CODE, msgLen, pBuf );
1992:
}
1993:
1994:
if ( (pBuf != NULL) && (allocated == TRUE) )
1995:
{
1996:
osal_mem_free( pBuf );
1997:
}
1998:
1999:
return ( deallocateIncoming );
2000: }
2001:
2002: /*********************************************************************
2003: * @fn
processEventsGAP
2004: *
2005: * @brief
Process an incoming GAP Event messages.
2006: *
2007: * @param
pMsg - message to process
2008: * @param
pOutMsg - outgoing message to be built
2009: * @param
pMsgLen - length of outgoing message
2010: * @param
pAllocated - whether outgoing message is locally allocated
2011: *
2012: * @return outgoing message

34/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2013: */
2014: static uint8 *processEventsGAP( gapEventHdr_t *pMsg, uint8 *pOutMsg, uint8
*pMsgLen, uint8 *pAllocated )
2015: {
2016:
uint8 msgLen = 0;
2017:
uint8 *pBuf = NULL;
2018:
2019:
switch ( pMsg->opcode )
2020:
{
2021:
case GAP_DEVICE_INIT_DONE_EVENT:
2022:
{
2023:
gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
2024:
2025:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_DEVICE_INIT_DONE_EVENT );
2026:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_DEVICE_INIT_DONE_EVENT );
2027:
pOutMsg[2] = pPkt->hdr.status;
2028:
VOID osal_memcpy( &pOutMsg[3], pPkt->devAddr, B_ADDR_LEN );
2029:
pOutMsg[9] = LO_UINT16( pPkt->dataPktLen );
2030:
pOutMsg[10] = HI_UINT16( pPkt->dataPktLen );
2031:
pOutMsg[11] = pPkt->numDataPkts;
2032:
2033:
// Copy the Device's local keys
2034:
VOID osal_memcpy( &pOutMsg[12], IRK, KEYLEN );
2035:
VOID osal_memcpy( &pOutMsg[12+KEYLEN], SRK, KEYLEN );
2036:
2037:
if ( pPkt->hdr.status == SUCCESS )
2038:
{
2039:
VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, IRK );
2040:
VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, SRK );
2041:
VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ),
&hciExtSignCounter );
2042:
}
2043:
2044:
pBuf = pOutMsg;
2045:
msgLen = 44;
2046:
}
2047:
break;
2048:
2049:
case GAP_DEVICE_DISCOVERY_EVENT:
2050:
{
2051:
gapDevDiscEvent_t *pPkt = (gapDevDiscEvent_t *)pMsg;
2052:
2053:
if ( (pPkt->hdr.status == SUCCESS) && (pPkt->numDevs > 0) )
2054:
{
2055:
uint8 x;
2056:
gapDevRec_t *devList = pPkt->pDevList;
2057:
2058:
// Calculate buffer needed
2059:
msgLen = 4; // Size of opCode, status and numDevs field
2060:
msgLen += (pPkt->numDevs * 8); // Num devices * (eventType, addrType,
addr)
2061:
2062:
pBuf = osal_mem_alloc( msgLen );
2063:
if ( pBuf )
2064:
{
2065:
uint8 *buf = pBuf;
2066:
2067:
// Fill in header
2068:
*buf++ = LO_UINT16( HCI_EXT_GAP_DEVICE_DISCOVERY_EVENT );
2069:
*buf++ = HI_UINT16( HCI_EXT_GAP_DEVICE_DISCOVERY_EVENT );
2070:
*buf++ = pPkt->hdr.status;
2071:
*buf++ = pPkt->numDevs;

35/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2072:
2073:
2074:
2075:
2076:
2077:
2078:
2079:
2080:
2081:
2082:
2083:
2084:
2085:
2086:
2087:
2088:
2089:
2090:
2091:
2092:
2093:
2094:
2095:
2096:
2097:
2098:
2099:
2100:
2101:
2102:
2103:
2104:
2105:
2106:
2107:
2108:
2109:
2110:
2111:
2112:
2113:
2114:
2115:
2116:
2117:
2118:
2119:
2120:
2121:
2122:
2123:
2124:
2125:
2126:
2127:
2128:
2129:
2130:
2131:
2132:

devList = pPkt->pDevList;
for ( x = 0; x < pPkt->numDevs; x++, devList++ )
{
*buf++ = devList->eventType;
*buf++ = devList->addrType;
VOID osal_memcpy( buf, devList->addr, B_ADDR_LEN );
buf += B_ADDR_LEN;
}
*pAllocated = TRUE;
}
else
{
pPkt->hdr.status = bleMemAllocError;
}
}
if ( (pPkt->hdr.status != SUCCESS) || (pPkt->numDevs == 0) )
{
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_DEVICE_DISCOVERY_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_DEVICE_DISCOVERY_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = 0;
pBuf = pOutMsg;
msgLen = 4; // Size of opCode, status and numDevs field
}
}
break;
case GAP_ADV_DATA_UPDATE_DONE_EVENT:
{
gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_ADV_DATA_UPDATE_DONE_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_ADV_DATA_UPDATE_DONE_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = pPkt->adType;
pBuf = pOutMsg;
msgLen = 4;
}
break;
case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
{
gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t
*)pMsg;
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_MAKE_DISCOVERABLE_DONE_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_MAKE_DISCOVERABLE_DONE_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = LO_UINT16( pPkt->interval );
pOutMsg[4] = HI_UINT16( pPkt->interval );
pBuf = pOutMsg;
msgLen = 5;
}
break;
case GAP_END_DISCOVERABLE_DONE_EVENT:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_END_DISCOVERABLE_DONE_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_END_DISCOVERABLE_DONE_EVENT );
pOutMsg[2] = pMsg->hdr.status;

36/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2133:
pBuf = pOutMsg;
2134:
msgLen = 3;
2135:
break;
2136:
2137:
case GAP_LINK_ESTABLISHED_EVENT:
2138:
{
2139:
gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;
2140:
2141: #if defined ( GAP_BOND_MGR )
2142:
if ( pPkt->hdr.status == SUCCESS )
2143:
{
2144:
// Notify the Bond Manager to the connection
2145:
GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt>connectionHandle, hciExtProfileRole );
2146:
}
2147: #endif
2148:
2149:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_LINK_ESTABLISHED_EVENT );
2150:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_LINK_ESTABLISHED_EVENT );
2151:
pOutMsg[2] = pPkt->hdr.status;
2152:
pOutMsg[3] = pPkt->devAddrType;
2153:
VOID osal_memcpy( &(pOutMsg[4]), pPkt->devAddr, B_ADDR_LEN );
2154:
pOutMsg[10] = LO_UINT16( pPkt->connectionHandle );
2155:
pOutMsg[11] = HI_UINT16( pPkt->connectionHandle );
2156:
pOutMsg[12] = LO_UINT16( pPkt->connInterval );
2157:
pOutMsg[13] = HI_UINT16( pPkt->connInterval );
2158:
pOutMsg[14] = LO_UINT16( pPkt->connLatency );
2159:
pOutMsg[15] = HI_UINT16( pPkt->connLatency );
2160:
pOutMsg[16] = LO_UINT16( pPkt->connTimeout );
2161:
pOutMsg[17] = HI_UINT16( pPkt->connTimeout );
2162:
pOutMsg[18] = pPkt->clockAccuracy;
2163:
pBuf = pOutMsg;
2164:
msgLen = 19;
2165:
}
2166:
break;
2167:
2168:
case GAP_LINK_TERMINATED_EVENT:
2169:
{
2170:
gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
2171:
2172: #if defined ( GAP_BOND_MGR )
2173:
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
2174: #endif
2175:
2176:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_LINK_TERMINATED_EVENT );
2177:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_LINK_TERMINATED_EVENT );
2178:
pOutMsg[2] = pPkt->hdr.status;
2179:
pOutMsg[3] = LO_UINT16( pPkt->connectionHandle );
2180:
pOutMsg[4] = HI_UINT16( pPkt->connectionHandle );
2181:
pOutMsg[5] = pPkt->reason;
2182:
pBuf = pOutMsg;
2183:
msgLen = 6;
2184:
}
2185:
break;
2186:
2187:
case GAP_LINK_PARAM_UPDATE_EVENT:
2188:
{
2189:
gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;
2190:
2191:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_LINK_PARAM_UPDATE_EVENT );
2192:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_LINK_PARAM_UPDATE_EVENT );
2193:
pOutMsg[2] = pPkt->hdr.status;

37/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2194:
2195:
2196:
2197:
2198:
2199:
2200:
2201:
2202:
2203:
2204:
2205:
2206:
2207:
2208:
2209:
2210:
2211:
2212:
2213:
2214:
2215:
2216:
2217:
2218:
2219:
2220:
2221:
2222:
2223:
2224:
2225:
2226:
2227:
2228:
2229:
2230:
2231:
2232:
2233:
2234:
2235:
2236:
2237:
2238:
2239:
2240:
2241:
2242:
2243:
2244:
2245:
2246:
2247:
2248:
2249:
2250:
2251:
2252:
2253:
2254:
2255:

pOutMsg[3] = LO_UINT16(
pOutMsg[4] = HI_UINT16(
pOutMsg[5] = LO_UINT16(
pOutMsg[6] = HI_UINT16(
pOutMsg[7] = LO_UINT16(
pOutMsg[8] = HI_UINT16(
pOutMsg[9] = LO_UINT16(
pOutMsg[10] = HI_UINT16(
pBuf = pOutMsg;
msgLen = 11;

pPkt->connectionHandle );
pPkt->connectionHandle );
pPkt->connInterval );
pPkt->connInterval );
pPkt->connLatency );
pPkt->connLatency );
pPkt->connTimeout );
pPkt->connTimeout );

}
break;
case GAP_RANDOM_ADDR_CHANGED_EVENT:
{
gapRandomAddrEvent_t *pPkt = (gapRandomAddrEvent_t *)pMsg;
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_RANDOM_ADDR_CHANGED_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_RANDOM_ADDR_CHANGED_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = pPkt->addrType;
VOID osal_memcpy( &(pOutMsg[4]), pPkt->newRandomAddr, B_ADDR_LEN );
pBuf = pOutMsg;
msgLen = 10;
}
break;
case GAP_SIGNATURE_UPDATED_EVENT:
{
gapSignUpdateEvent_t *pPkt = (gapSignUpdateEvent_t *)pMsg;
#if defined ( GAP_BOND_MGR )
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
#endif
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_SIGNATURE_UPDATED_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_SIGNATURE_UPDATED_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = pPkt->addrType;
VOID osal_memcpy( &(pOutMsg[4]), pPkt->devAddr, B_ADDR_LEN );
pOutMsg[10] = BREAK_UINT32( pPkt->signCounter, 0 );
pOutMsg[11] = BREAK_UINT32( pPkt->signCounter, 1 );
pOutMsg[12] = BREAK_UINT32( pPkt->signCounter, 2 );
pOutMsg[13] = BREAK_UINT32( pPkt->signCounter, 3 );
pBuf = pOutMsg;
msgLen = 14;
}
break;
case GAP_PASSKEY_NEEDED_EVENT:
{
gapPasskeyNeededEvent_t *pPkt = (gapPasskeyNeededEvent_t *)pMsg;
#if defined ( GAP_BOND_MGR )
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
#endif
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_PASSKEY_NEEDED_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_PASSKEY_NEEDED_EVENT );
pOutMsg[2] = pPkt->hdr.status;
VOID osal_memcpy( &(pOutMsg[3]), pPkt->deviceAddr, B_ADDR_LEN );
pOutMsg[9] = LO_UINT16( pPkt->connectionHandle );
pOutMsg[10] = HI_UINT16( pPkt->connectionHandle );

38/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2256:
pOutMsg[11] = pPkt->uiInputs;
2257:
pOutMsg[12] = pPkt->uiOutputs;
2258:
pBuf = pOutMsg;
2259:
msgLen = 13;
2260:
}
2261:
break;
2262:
2263:
case GAP_AUTHENTICATION_COMPLETE_EVENT:
2264:
{
2265:
gapAuthCompleteEvent_t *pPkt = (gapAuthCompleteEvent_t *)pMsg;
2266:
2267: #if defined ( GAP_BOND_MGR )
2268:
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
2269: #endif
2270:
2271:
msgLen = 106;
2272:
2273:
pBuf = osal_mem_alloc( msgLen );
2274:
if ( pBuf )
2275:
{
2276:
uint8 *buf = pBuf;
2277:
2278:
*pAllocated = TRUE;
2279:
2280:
VOID osal_memset( buf, 0, msgLen );
2281:
2282:
*buf++ = LO_UINT16( HCI_EXT_GAP_AUTH_COMPLETE_EVENT );
2283:
*buf++ = HI_UINT16( HCI_EXT_GAP_AUTH_COMPLETE_EVENT );
2284:
*buf++ = pPkt->hdr.status;
2285:
*buf++ = LO_UINT16( pPkt->connectionHandle );
2286:
*buf++ = HI_UINT16( pPkt->connectionHandle );
2287:
*buf++ = pPkt->authState;
2288:
2289:
if ( pPkt->pSecurityInfo )
2290:
{
2291:
*buf++ = TRUE;
2292:
*buf++ = pPkt->pSecurityInfo->keySize;
2293:
VOID osal_memcpy( buf, pPkt->pSecurityInfo->ltk, KEYLEN );
2294:
buf += KEYLEN;
2295:
*buf++ = LO_UINT16( pPkt->pSecurityInfo->div );
2296:
*buf++ = HI_UINT16( pPkt->pSecurityInfo->div );
2297:
VOID osal_memcpy( buf, pPkt->pSecurityInfo->rand, B_RANDOM_NUM_SIZE
);
2298:
buf += B_RANDOM_NUM_SIZE;
2299:
}
2300:
else
2301:
{
2302:
// Skip securityInfo
2303:
buf += 1 + KEYLEN + B_RANDOM_NUM_SIZE + 2 + 1;
2304:
}
2305:
2306:
if ( pPkt->pDevSecInfo )
2307:
{
2308:
*buf++ = TRUE;
2309:
*buf++ = pPkt->pDevSecInfo->keySize;
2310:
VOID osal_memcpy( buf, pPkt->pDevSecInfo->ltk, KEYLEN );
2311:
buf += KEYLEN;
2312:
*buf++ = LO_UINT16( pPkt->pDevSecInfo->div );
2313:
*buf++ = HI_UINT16( pPkt->pDevSecInfo->div );
2314:
VOID osal_memcpy( buf, pPkt->pDevSecInfo->rand, B_RANDOM_NUM_SIZE );
2315:
buf += B_RANDOM_NUM_SIZE;
2316:
}

39/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2317:
else
2318:
{
2319:
// Skip securityInfo
2320:
buf += 1 + KEYLEN + B_RANDOM_NUM_SIZE + 2 + 1;
2321:
}
2322:
2323:
if ( pPkt->pIdentityInfo )
2324:
{
2325:
*buf++ = TRUE;
2326:
VOID osal_memcpy( buf, pPkt->pIdentityInfo->irk, KEYLEN );
2327:
buf += KEYLEN;
2328:
VOID osal_memcpy( buf, pPkt->pIdentityInfo->bd_addr, B_ADDR_LEN );
2329:
buf += B_ADDR_LEN;
2330:
}
2331:
else
2332:
{
2333:
// Skip identityInfo
2334:
buf += KEYLEN + B_ADDR_LEN + 1;
2335:
}
2336:
2337:
if ( pPkt->pSigningInfo )
2338:
{
2339:
*buf++ = TRUE;
2340:
VOID osal_memcpy( buf, pPkt->pSigningInfo->srk, KEYLEN );
2341:
buf += KEYLEN;
2342:
*buf++ = BREAK_UINT32( pPkt->pSigningInfo->signCounter, 0 );
2343:
*buf++ = BREAK_UINT32( pPkt->pSigningInfo->signCounter, 1 );
2344:
*buf++ = BREAK_UINT32( pPkt->pSigningInfo->signCounter, 2 );
2345:
*buf = BREAK_UINT32( pPkt->pSigningInfo->signCounter, 3 );
2346:
}
2347:
}
2348:
else
2349:
{
2350:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_AUTH_COMPLETE_EVENT );
2351:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_AUTH_COMPLETE_EVENT );
2352:
pOutMsg[2] = bleMemAllocError;
2353:
pOutMsg[3] = LO_UINT16( pPkt->connectionHandle );
2354:
pOutMsg[4] = HI_UINT16( pPkt->connectionHandle );
2355:
pBuf = pOutMsg;
2356:
msgLen = 5;
2357:
}
2358:
}
2359:
break;
2360:
2361:
case GAP_BOND_COMPLETE_EVENT:
2362:
{
2363:
gapBondCompleteEvent_t *pPkt = (gapBondCompleteEvent_t *)pMsg;
2364:
2365: #if defined ( GAP_BOND_MGR )
2366:
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
2367: #endif
2368:
2369:
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_BOND_COMPLETE_EVENT );
2370:
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_BOND_COMPLETE_EVENT );
2371:
pOutMsg[2] = pPkt->hdr.status;
2372:
pOutMsg[3] = LO_UINT16( pPkt->connectionHandle );
2373:
pOutMsg[4] = HI_UINT16( pPkt->connectionHandle );
2374:
pBuf = pOutMsg;
2375:
msgLen = 5;
2376:
}
2377:
break;
2378:

40/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2379:
2380:
2381:
2382:
2383:
2384:
2385:
2386:
2387:
2388:
2389:
2390:
2391:
2392:
2393:
2394:
2395:
2396:
2397:
2398:
2399:
2400:
2401:
2402:
2403:
2404:
2405:
2406:
2407:
2408:
2409:
2410:
2411:
2412:
2413:
2414:
2415:
2416:
2417:
2418:
2419:
2420:
2421:
2422:
2423:
2424:
2425:
2426:
2427:
2428:
2429:
2430:
2431:
2432:
2433:
2434:
2435:
2436:
2437:
2438:
2439:
2440:

case GAP_PAIRING_REQ_EVENT:
{
gapPairingReqEvent_t *pPkt = (gapPairingReqEvent_t *)pMsg;
uint8 tmp = 0;
#if defined ( GAP_BOND_MGR )
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
#endif
pOutMsg[0]
pOutMsg[1]
pOutMsg[2]
pOutMsg[3]
pOutMsg[4]
pOutMsg[5]
pOutMsg[6]
pOutMsg[7]
pOutMsg[8]

=
=
=
=
=
=
=
=
=

LO_UINT16( HCI_EXT_GAP_PAIRING_REQ_EVENT );
HI_UINT16( HCI_EXT_GAP_PAIRING_REQ_EVENT );
pPkt->hdr.status;
LO_UINT16( pPkt->connectionHandle );
HI_UINT16( pPkt->connectionHandle );
pPkt->pairReq.ioCap;
pPkt->pairReq.oobDataFlag;
pPkt->pairReq.authReq;
pPkt->pairReq.maxEncKeySize;

tmp |= ( pPkt->pairReq.keyDist.sEncKey ) ? KEYDIST_SENC : 0;


tmp |= ( pPkt->pairReq.keyDist.sIdKey ) ? KEYDIST_SID : 0;
tmp |= ( pPkt->pairReq.keyDist.sSign ) ? KEYDIST_SSIGN : 0;
tmp |= ( pPkt->pairReq.keyDist.mEncKey ) ? KEYDIST_MENC : 0;
tmp |= ( pPkt->pairReq.keyDist.mIdKey ) ? KEYDIST_MID : 0;
tmp |= ( pPkt->pairReq.keyDist.mSign ) ? KEYDIST_MSIGN : 0;
pOutMsg[9] = tmp;
pBuf = pOutMsg;
msgLen = 10;
}
break;
case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
{
gapSlaveSecurityReqEvent_t *pPkt = (gapSlaveSecurityReqEvent_t *)pMsg;
#if defined ( GAP_BOND_MGR )
GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
#endif
pOutMsg[0] = LO_UINT16( HCI_EXT_GAP_SLAVE_REQUESTED_SECURITY_EVENT );
pOutMsg[1] = HI_UINT16( HCI_EXT_GAP_SLAVE_REQUESTED_SECURITY_EVENT );
pOutMsg[2] = pPkt->hdr.status;
pOutMsg[3] = LO_UINT16( pPkt->connectionHandle );
pOutMsg[4] = HI_UINT16( pPkt->connectionHandle );
VOID osal_memcpy( &(pOutMsg[5]), pPkt->deviceAddr, B_ADDR_LEN );
pOutMsg[11] = pPkt->authReq;
pBuf = pOutMsg;
msgLen = 12;
}
break;
case GAP_DEVICE_INFO_EVENT:
{
gapDeviceInfoEvent_t *pPkt = (gapDeviceInfoEvent_t *)pMsg;
msgLen = 13 + pPkt->dataLen;
pBuf = osal_mem_alloc( msgLen );
if ( pBuf )
{
uint8 *buf = pBuf;

41/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2441:
2442:
// Fill in header
2443:
*buf++ = LO_UINT16( HCI_EXT_GAP_DEVICE_INFO_EVENT );
2444:
*buf++ = HI_UINT16( HCI_EXT_GAP_DEVICE_INFO_EVENT );
2445:
*buf++ = pPkt->hdr.status;
2446:
*buf++ = pPkt->eventType;
2447:
*buf++ = pPkt->addrType;
2448:
2449:
VOID osal_memcpy( buf, pPkt->addr, B_ADDR_LEN );
2450:
buf += B_ADDR_LEN;
2451:
2452:
*buf++ = (uint8)pPkt->rssi;
2453:
*buf++ = pPkt->dataLen;
2454:
VOID osal_memcpy( buf, pPkt->pEvtData, pPkt->dataLen );
2455:
2456:
*pAllocated = TRUE;
2457:
}
2458:
else
2459:
{
2460:
pPkt->hdr.status = bleMemAllocError;
2461:
}
2462:
}
2463:
break;
2464:
2465:
default:
2466:
// Unknown command
2467:
break;
2468:
}
2469:
2470:
*pMsgLen = msgLen;
2471:
2472:
return ( pBuf );
2473: }
2474:
2475: /*********************************************************************
2476: * @fn
processEventsL2CAP
2477: *
2478: * @brief
Process an incoming L2CAP Event messages.
2479: *
2480: * @param
pPkt - packet to process
2481: * @param
pOutMsg - outgoing message to be built
2482: * @param
pMsgLen - length of outgoing message
2483: *
2484: * @return outgoing message
2485: */
2486: static uint8 *processEventsL2CAP( l2capSignalEvent_t *pPkt, uint8 *pOutMsg,
uint8 *pMsgLen )
2487: {
2488:
uint8 msgLen;
2489:
2490:
// Build the message header first
2491:
msgLen = buildHCIExtHeader( pOutMsg, (HCI_EXT_L2CAP_EVENT | pPkt->opcode),
2492:
pPkt->hdr.status, pPkt->connHandle );
2493:
2494:
if ( pPkt->hdr.status == SUCCESS )
2495:
{
2496:
// Build the message
2497:
switch ( pPkt->opcode )
2498:
{
2499:
case L2CAP_CMD_REJECT:
2500:
msgLen += L2CAP_BuildCmdReject( &pOutMsg[msgLen], (uint8 *)&(pPkt>cmd.cmdReject) );

42/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2501:
2502:
2503:
2504:

break;

case L2CAP_INFO_RSP:
msgLen += L2CAP_BuildInfoRsp( &pOutMsg[msgLen], (uint8 *)&(pPkt>cmd.infoRsp) );
2505:
break;
2506:
2507:
case L2CAP_PARAM_UPDATE_RSP:
2508:
msgLen += L2CAP_BuildParamUpdateRsp( &pOutMsg[msgLen], (uint8 *)&(pPkt>cmd.updateRsp) );
2509:
break;
2510:
2511:
default:
2512:
// Unknown command
2513:
break;
2514:
}
2515:
}
2516:
2517:
*pMsgLen = msgLen;
2518:
2519:
return ( pOutMsg );
2520: }
2521:
2522: /*********************************************************************
2523: * @fn
processEventsGATT
2524: *
2525: * @brief
Process an incoming GATT Event messages.
2526: *
2527: * @param
pPkt - packet to process
2528: * @param
pMsg - outgoing message to be built
2529: * @param
pMsgLen - length of outgoing message
2530: * @param
pAllocated - whether outgoing message is locally allocated
2531: *
2532: * @return outgoing message
2533: */
2534: static uint8 *processEventsGATT( gattMsgEvent_t *pPkt, uint8 *pMsg, uint8
*pMsgLen, uint8 *pAllocated )
2535: {
2536:
uint8 hdrLen = HCI_EXT_HDR_LEN + 1; // hdr + event length
2537:
uint8 msgLen = 0;
2538:
uint8 *pBuf = pMsg;
2539:
2540:
*pAllocated = FALSE;
2541:
2542:
if ( pPkt->hdr.status == SUCCESS )
2543:
{
2544:
// Build the message first
2545:
switch ( pPkt->method )
2546:
{
2547:
case ATT_ERROR_RSP:
2548:
msgLen = ATT_BuildErrorRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.errorRsp) );
2549:
break;
2550:
2551:
case ATT_EXCHANGE_MTU_REQ:
2552:
msgLen = ATT_BuildExchangeMTUReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.exchangeMTUReq) );
2553:
break;
2554:
2555:
case ATT_EXCHANGE_MTU_RSP:
2556:
msgLen = ATT_BuildExchangeMTURsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.exchangeMTURsp) );

43/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2557:
2558:
2559:
2560:

break;

case ATT_FIND_INFO_REQ:
msgLen = ATT_BuildFindInfoReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.findInfoReq) );
2561:
break;
2562:
2563:
case ATT_FIND_INFO_RSP:
2564:
msgLen = ATT_BuildFindInfoRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.findInfoRsp) );
2565:
break;
2566:
2567:
case ATT_FIND_BY_TYPE_VALUE_REQ:
2568:
msgLen = ATT_BuildFindByTypeValueReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.findByTypeValueReq) );
2569:
break;
2570:
2571:
case ATT_FIND_BY_TYPE_VALUE_RSP:
2572:
msgLen = ATT_BuildFindByTypeValueRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.findByTypeValueRsp) );
2573:
break;
2574:
2575:
case ATT_READ_BY_TYPE_REQ:
2576:
msgLen = ATT_BuildReadByTypeReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readByTypeReq) );
2577:
break;
2578:
2579:
case ATT_READ_BY_TYPE_RSP:
2580:
msgLen = ATT_BuildReadByTypeRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readByTypeRsp) );
2581:
break;
2582:
2583:
case ATT_READ_REQ:
2584:
msgLen = ATT_BuildReadReq( &pMsg[hdrLen], (uint8 *)&(pPkt->msg.readReq)
);
2585:
break;
2586:
2587:
case ATT_READ_RSP:
2588:
msgLen = ATT_BuildReadRsp( &pMsg[hdrLen], (uint8 *)&(pPkt->msg.readRsp)
);
2589:
break;
2590:
2591:
case ATT_READ_BLOB_REQ:
2592:
msgLen = ATT_BuildReadBlobReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readBlobReq) );
2593:
break;
2594:
2595:
case ATT_READ_BLOB_RSP:
2596:
msgLen = ATT_BuildReadBlobRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readBlobRsp) );
2597:
break;
2598:
2599:
case ATT_READ_MULTI_REQ:
2600:
msgLen = ATT_BuildReadMultiReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readMultiReq) );
2601:
break;
2602:
2603:
case ATT_READ_MULTI_RSP:
2604:
msgLen = ATT_BuildReadMultiRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readMultiRsp) );
2605:
break;
2606:

44/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2607:
2608:

case ATT_READ_BY_GRP_TYPE_REQ:
msgLen = ATT_BuildReadByTypeReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readByGrpTypeReq) );
2609:
break;
2610:
2611:
case ATT_READ_BY_GRP_TYPE_RSP:
2612:
msgLen = ATT_BuildReadByGrpTypeRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.readByGrpTypeRsp) );
2613:
break;
2614:
2615:
case ATT_WRITE_REQ:
2616:
pMsg[hdrLen] = pPkt->msg.writeReq.sig;
2617:
pMsg[hdrLen+1] = pPkt->msg.writeReq.cmd;
2618:
msgLen = 2;
2619:
msgLen += ATT_BuildWriteReq( &pMsg[hdrLen+2], (uint8 *)&(pPkt>msg.writeReq) );
2620:
break;
2621:
2622:
case ATT_WRITE_RSP:
2623:
msgLen = 0;
2624:
break;
2625:
2626:
case ATT_PREPARE_WRITE_REQ:
2627:
msgLen = ATT_BuildPrepareWriteReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.prepareWriteReq) );
2628:
break;
2629:
2630:
case ATT_PREPARE_WRITE_RSP:
2631:
msgLen = ATT_BuildPrepareWriteRsp( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.prepareWriteRsp) );
2632:
break;
2633:
2634:
case ATT_EXECUTE_WRITE_REQ:
2635:
msgLen = ATT_BuildExecuteWriteReq( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.executeWriteReq) );
2636:
break;
2637:
2638:
case ATT_EXECUTE_WRITE_RSP:
2639:
msgLen = 0;
2640:
break;
2641:
2642:
case ATT_HANDLE_VALUE_IND:
2643:
case ATT_HANDLE_VALUE_NOTI:
2644:
msgLen = ATT_BuildHandleValueInd( &pMsg[hdrLen], (uint8 *)&(pPkt>msg.handleValueInd) );
2645:
break;
2646:
2647:
case ATT_HANDLE_VALUE_CFM:
2648:
msgLen = 0;
2649:
break;
2650:
2651:
default:
2652:
// Unknown command
2653:
msgLen = 0;
2654:
break;
2655:
}
2656:
}
2657:
2658:
// Build the message header
2659:
VOID buildHCIExtHeader( pBuf, (HCI_EXT_ATT_EVENT | pPkt->method), pPkt>hdr.status, pPkt->connHandle );
2660:

45/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2661:
2662:
2663:
2664:
2665:
2666:
2667:
2668:
2669:
2670:
2671:
2672:
2673:
2674:
2675:
2676:
2677:
2678:
2679:
2680:
2681:
2682:
2683:
2684:
2685:
2686:
2687:
2688:
2689:
2690:
2691:
2692:
2693:
2694:

// Add the event (PDU) length for GATT events for now!
pBuf[HCI_EXT_HDR_LEN] = msgLen;
*pMsgLen = hdrLen + msgLen;
return ( pBuf );
}
#ifndef GATT_DB_OFF_CHIP
/*********************************************************************
* @fn
processEventsGATTServ
*
* @brief
Process an incoming GATT Server Event messages.
*
* @param
pPkt - packet to process
* @param
pMsg - outgoing message to be built
* @param
pMsgLen - length of outgoing message
*
* @return outgoing message
*/
static uint8 *processEventsGATTServ( gattEventHdr_t *pPkt, uint8 *pMsg, uint8
*pMsgLen )
{
uint8 hdrLen = HCI_EXT_HDR_LEN + 1; // hdr + event length
uint8 msgLen = 0;
uint8 *pBuf = pMsg;
if ( pPkt->hdr.status == SUCCESS )
{
// Build the message first
switch ( pPkt->method )
{
case GATT_CLIENT_CHAR_CFG_UPDATED_EVENT:
{
gattClientCharCfgUpdatedEvent_t *pEvent =
(gattClientCharCfgUpdatedEvent_t *)pPkt;

2695:
2696: #if defined ( GAP_BOND_MGR )
2697:
VOID GAPBondMgr_UpdateCharCfg( pEvent->connHandle, pEvent->attrHandle,
pEvent->value );
2698: #endif
2699:
// Attribute handle
2700:
pMsg[hdrLen]
= LO_UINT16( pEvent->attrHandle );
2701:
pMsg[hdrLen+1] = HI_UINT16( pEvent->attrHandle );
2702:
2703:
// Attribute value
2704:
pMsg[hdrLen+2] = LO_UINT16( pEvent->value );
2705:
pMsg[hdrLen+3] = HI_UINT16( pEvent->value );
2706:
2707:
msgLen = 4;
2708:
}
2709:
break;
2710:
2711:
default:
2712:
// Unknown command
2713:
break;
2714:
}
2715:
}
2716:
2717:
// Build the message header
2718:
VOID buildHCIExtHeader( pBuf, (HCI_EXT_GATT_EVENT | pPkt->method), pPkt>hdr.status, pPkt->connHandle );

46/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2719:
2720:
2721:
2722:
2723:
2724:
2725:
2726:
2727:
2728:
2729:
2730:
2731:
2732:
2733:
2734:
2735:
2736:
2737:
2738:
2739:
2740:
2741:
2742:
2743:
2744:
2745:
2746:
2747:
2748:
2749:
2750:
2751:
2752:
2753:
2754:
2755:
2756:
2757:
2758:
2759:
2760:
2761:
2762:
2763:
2764:
2765:
2766:
2767:
2768:
2769:
2770:
2771:
2772:
2773:
2774:
2775:
2776:
2777:
2778:
2779:

// Add the event (PDU) length for GATT events for now!
pBuf[HCI_EXT_HDR_LEN] = msgLen;
*pMsgLen = hdrLen + msgLen;
return ( pBuf );
}
#endif // !GATT_DB_OFF_CHIP
/*********************************************************************
* @fn
buildHCIExtHeader
*
* @brief
Build an HCI Exension header.
*
* @param
pBuf - header to be built
* @param
event - event id
* @param
status - event status
* @param
connHandle - connection handle
*
* @return header length
*/
static uint8 buildHCIExtHeader( uint8 *pBuf, uint16 event, uint8 status, uint16
connHandle )
{
pBuf[0] = LO_UINT16( event );
pBuf[1] = HI_UINT16( event );
pBuf[2] = status;
pBuf[3] = LO_UINT16( connHandle );
pBuf[4] = HI_UINT16( connHandle );
return ( HCI_EXT_HDR_LEN );
}
/*********************************************************************
* @fn
mapATT2BLEStatus
*
* @brief
Map ATT error code to BLE Generic status code.
*
* @param
status - ATT status
*
* @return BLE Generic status
*/
static uint8 mapATT2BLEStatus( uint8 status )
{
uint8 stat;
switch ( status )
{
case ATT_ERR_INVALID_PDU:
// Returned from Parse routines
stat = bleInvalidPDU;
break;
case ATT_ERR_INSUFFICIENT_AUTHEN:
// Returned from Send routines
stat = bleInsufficientAuthen;
break;
case ATT_ERR_INSUFFICIENT_ENCRYPT:
// Returned from Send routines
stat = bleInsufficientEncrypt;

47/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2780:
2781:
2782:
2783:
2784:
2785:
2786:
2787:
2788:
2789:
2790:
2791:
2792:
2793:
2794:
2795:
2796:
2797:
2798:
2799:
2800:
2801:
2802:
2803:
2804:
2805:
2806:
2807:
2808:
2809:
2810:

break;
case ATT_ERR_INSUFFICIENT_KEY_SIZE:
// Returned from Send routines
stat = bleInsufficientKeySize;
break;
default:
stat = status;
}
return ( stat );
}

#ifdef GATT_DB_OFF_CHIP
/*********************************************************************
* @fn
addAttrRec
*
* @brief
Add attribute record to its service.
*
* @param
pServ - GATT service
* @param
pUUID - attribute UUID
* @param
len - length of UUID
* @param
permissions - attribute permissions
* @param
pTotalAttrs - total number of attributes
* @param
pRspDataLen - response data length to be returned
*
* @return status
*/
static uint8 addAttrRec( gattService_t *pServ, uint8 *pUUID, uint8 len,
uint8 permissions, uint16 *pTotalAttrs, uint8
*pRspDataLen )
2811: {
2812:
gattAttribute_t *pAttr = &(pServ->attrs[pServ->numAttrs]);
2813:
uint8 stat = SUCCESS;
2814:
2815:
// Set up attribute record
2816:
pAttr->type.uuid = findUUIDRec( pUUID, len );
2817:
if ( pAttr->type.uuid != NULL )
2818:
{
2819:
pAttr->type.len = len;
2820:
pAttr->permissions = permissions;
2821:
2822:
// Are all attributes added to the service yet?
2823:
if ( ++pServ->numAttrs == *pTotalAttrs )
2824:
{
2825:
// Register the service with the GATT Server
2826:
stat = GATT_RegisterService( pServ );
2827:
if ( stat == SUCCESS )
2828:
{
2829:
*pRspDataLen = 4;
2830:
2831:
// Service startHandle
2832:
uint16 handle = pServ->attrs[0].handle;
2833:
rspBuf[RSP_PAYLOAD_IDX] = LO_UINT16( handle );
2834:
rspBuf[RSP_PAYLOAD_IDX+1] = HI_UINT16( handle );
2835:
2836:
// Service endHandle
2837:
handle = pServ->attrs[pServ->numAttrs-1].handle;
2838:
rspBuf[RSP_PAYLOAD_IDX+2] = LO_UINT16( handle );
2839:
rspBuf[RSP_PAYLOAD_IDX+3] = HI_UINT16( handle );
2840:

48/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2841:
2842:
2843:
2844:
2845:
2846:
2847:
2848:
2849:
2850:
2851:
2852:
2853:
2854:
2855:
2856:
2857:
2858:
2859:
2860:
2861:
2862:
2863:
2864:
2865:
2866:
2867:
2868:
2869:
2870:
2871:
2872:
2873:
2874:
2875:
2876:
2877:
2878:
2879:
2880:
2881:
2882:
2883:
2884:
2885:
2886:
2887:
2888:
2889:
2890:
2891:
2892:
2893:
2894:
2895:
2896:
2897:
2898:
2899:
2900:
2901:
2902:

// Service is registered with GATT; clear its info


pServ->attrs = NULL;
pServ->numAttrs = 0;
}
else
{
freeAttrRecs( pServ );
}
// We're done with this service
*pTotalAttrs = 0;
}
}
else
{
stat = INVALIDPARAMETER;
}
return ( stat );
}
/*********************************************************************
* @fn
freeAttrRecs
*
* @brief
Free attribute records. Also, free UUIDs that were
*
allocated dynamically.
*
* @param
pServ - GATT service
*
* @return none
*/
static void freeAttrRecs( gattService_t *pServ )
{
if ( pServ->attrs != NULL )
{
for ( uint8 i = 0; i < pServ->numAttrs; i++ )
{
gattAttrType_t *pType = &pServ->attrs[i].type;
if ( pType->uuid != NULL )
{
if ( GATT_FindUUIDRec( (uint8 *)pType->uuid, pType->len ) == NULL )
{
// UUID was dynamically allocated; free it
osal_mem_free( (uint8 *)pType->uuid );
}
}
}
osal_mem_free( pServ->attrs );
pServ->attrs = NULL;
pServ->numAttrs = 0;
}
}
/*********************************************************************
* @fn
findUUIDRec
*
* @brief
Find UUID record. If the record is not found, create one
*
dynamically.
*
* @param
pUUID - UUID to look for

49/50

mikroC compiler for PIC by mikroElektronika

C:\Texas Instruments\BLE-CC254x-1.4.0\Projects\ble\HostTestApp - UserCmd\Source\hci_ext_app.c


6/12/2013 10:02:24

2903:
2904:
2905:
2906:
2907:
2908:
2909:
2910:
2911:
2912:
2913:
2914:
2915:
2916:
2917:
2918:
2919:
2920:
2921:
2922:
2923:
2924:
2925:
2926:

* @param
len - length of UUID
*
* @return UUID record
*/
static const uint8 *findUUIDRec( uint8 *pUUID, uint8 len )
{
const uint8 *pUuid = GATT_FindUUIDRec( pUUID, len );
if ( pUuid == NULL )
{
// UUID not found; allocate space for it
pUuid = osal_mem_alloc( len );
if ( pUuid != NULL )
{
VOID osal_memcpy( (uint8 *)pUuid, pUUID, len );
}
}
return ( pUuid );
}
#endif // GATT_DB_OFF_CHIP
/*********************************************************************
*********************************************************************/

50/50

mikroC compiler for PIC by mikroElektronika

You might also like