CC2640之添加自定义服务

一、简介

本文以SimpleBLEPeripheral工程为例,介绍如何在工程中添加一个自定义的服务


二、实验平台

协议栈版本:ble_cc26xx_2_01_00_44423

编译软件:IAR Embedded Workbench for ARM Version 7.40

硬件平台:CC26xxDK开发板

仿真器:XDS100V3(香瓜)

手机平台:小米4S

APP:BLE读写器


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:[email protected]

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
香瓜单片机之Linux群:512598061
香瓜单片机之职场交流群:450154342
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
暂无

2、在进行本文步骤前,请先 实现以下博文:
暂无


五、基础知识

暂无


六、实验步骤

1、编写并添加自定义的服务

1)写一个服务源文件GUA_Profile.c(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)

[cpp]  view plain  copy
  1. //******************************************************************************        
  2. //name:         GUA_profile.c        
  3. //introduce:    香瓜自定义的服务,内含一个可读、可写、可通知的特征值    
  4. //author:       甜甜的大香瓜      
  5. //email:        [email protected]       
  6. //QQ group      香瓜BLE之CC2640(557278427)     
  7. //changetime:   2016.08.27     
  8. //******************************************************************************    
  9. /*********************************************************************    
  10.  * INCLUDES    
  11.  */    
  12. #include <string.h>  
  13.   
  14. #include "bcomdef.h"    
  15. #include "OSAL.h"    
  16. #include "linkdb.h"    
  17. #include "att.h"    
  18. #include "gatt.h"    
  19. #include "gatt_uuid.h"    
  20. #include "gattservapp.h"    
  21. #include "gapbondmgr.h"    
  22.     
  23. #include "GUA_Profile.h"    
  24.     
  25. /*********************************************************************  
  26.  * MACROS  
  27.  */    
  28.     
  29. /*********************************************************************  
  30.  * CONSTANTS  
  31.  */    
  32.     
  33. #define SERVAPP_NUM_ATTR_SUPPORTED              5    
  34.     
  35. //属性在属性表中的偏移值    
  36. #define ATTRTBL_GUA_CHAR1_IDX                   2    
  37. #define ATTRTBL_GUA_CHAR1_CCC_IDX               3    
  38. /*********************************************************************  
  39.  * TYPEDEFS  
  40.  */    
  41.     
  42. /*********************************************************************  
  43.  * GLOBAL VARIABLES  
  44.  */    
  45. // GUA Service UUID: 0xFFE0    
  46. CONST uint8 GUAServUUID[ATT_BT_UUID_SIZE] =    
  47. {     
  48.   LO_UINT16(GUAPROFILE_SERV_UUID), HI_UINT16(GUAPROFILE_SERV_UUID)    
  49. };    
  50.     
  51. // GUA char1 UUID: 0xFFE1    
  52. CONST uint8 GUAChar1UUID[ATT_BT_UUID_SIZE] =    
  53. {     
  54.   LO_UINT16(GUAPROFILE_CHAR1_UUID), HI_UINT16(GUAPROFILE_CHAR1_UUID)    
  55. };    
  56.     
  57. /*********************************************************************  
  58.  * EXTERNAL VARIABLES  
  59.  */    
  60.     
  61. /*********************************************************************  
  62.  * EXTERNAL FUNCTIONS  
  63.  */    
  64.     
  65. /*********************************************************************  
  66.  * LOCAL VARIABLES  
  67.  */    
  68.     
  69. static GUAProfileCBs_t *GUAProfile_AppCBs = NULL;    
  70.     
  71. /*********************************************************************  
  72.  * Profile Attributes - variables  
  73.  */    
  74.     
  75. // GUA Service attribute    
  76. static CONST gattAttrType_t GUAProfile_Service = { ATT_BT_UUID_SIZE, GUAServUUID };    
  77.     
  78. // GUA Characteristic 1 Properties    
  79. static uint8 GUAProfile_Char1_Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_NOTIFY;    
  80.     
  81. // GUA Characteristic 1 Value    
  82. static uint8 GUAProfile_Char1[GUAPROFILE_CHAR1_LEN] = {0};    
  83.     
  84. // GUA Characteristic 1 Configs    
  85. static gattCharCfg_t *GUAProfile_Char1_Config;    
  86.     
  87. // GUA Characteristic 1 User Description    
  88. static uint8 GUAProfile_Char1_UserDesp[10] = "GUA Char1\0";    
  89.     
  90.     
  91. /*********************************************************************  
  92.  * Profile Attributes - Table  
  93.  */    
  94.     
  95. static gattAttribute_t GUAProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =     
  96. {    
  97.   // GUA Service    
  98.   {     
  99.     { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */    
  100.     GATT_PERMIT_READ,                         /* permissions */    
  101.     0,                                        /* handle */    
  102.     (uint8 *)&GUAProfile_Service                       /* pValue */    
  103.   },    
  104.     
  105.     // GUA Characteristic 1 Declaration    
  106.     {     
  107.       { ATT_BT_UUID_SIZE, characterUUID },    
  108.       GATT_PERMIT_READ,     
  109.       0,    
  110.       &GUAProfile_Char1_Props     
  111.     },    
  112.     
  113.       // GUA Characteristic 1 Value    
  114.       {     
  115.         { ATT_BT_UUID_SIZE, GUAChar1UUID },    
  116.         GATT_PERMIT_READ | GATT_PERMIT_WRITE,     
  117.         0,     
  118.         GUAProfile_Char1    
  119.       },    
  120.     
  121.       // GUA Characteristic 1 configuration    
  122.       {     
  123.         { ATT_BT_UUID_SIZE, clientCharCfgUUID },    
  124.         GATT_PERMIT_READ | GATT_PERMIT_WRITE,     
  125.         0,     
  126.         (uint8 *)&GUAProfile_Char1_Config     
  127.       },    
  128.     
  129.       // GUA Characteristic 1 User Description    
  130.       {     
  131.         { ATT_BT_UUID_SIZE, charUserDescUUID },    
  132.         GATT_PERMIT_READ,     
  133.         0,     
  134.         GUAProfile_Char1_UserDesp     
  135.       },          
  136. };    
  137.     
  138.     
  139. /*********************************************************************  
  140.  * LOCAL FUNCTIONS  
  141.  */    
  142. static uint8 GUAProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,     
  143.                             uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen, uint8 method );    
  144. static bStatus_t GUAProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,    
  145.                                  uint8 *pValue, uint16 len, uint16 offset, uint8 method );    
  146.     
  147. /*********************************************************************  
  148.  * PROFILE CALLBACKS  
  149.  */    
  150. // GUAProfile Service Callbacks    
  151. CONST gattServiceCBs_t GUAProfileCBs =    
  152. {    
  153.   GUAProfile_ReadAttrCB,        // Read callback function pointer    
  154.   GUAProfile_WriteAttrCB,       // Write callback function pointer    
  155.   NULL                          // Authorization callback function pointer    
  156. };    
  157.     
  158. /*********************************************************************  
  159.  * PUBLIC FUNCTIONS  
  160.  */    
  161.     
  162. /*********************************************************************  
  163.  * @fn      GUAProfile_AddService  
  164.  *  
  165.  * @brief   Initializes the GUA service by registering  
  166.  *          GATT attributes with the GATT server.  
  167.  *  
  168.  * @param   services - services to add. This is a bit map and can  
  169.  *                     contain more than one service.  
  170.  *  
  171.  * @return  Success or Failure  
  172.  */    
  173. bStatus_t GUAProfile_AddService( uint32 services )    
  174. {    
  175.   uint8 status = SUCCESS;    
  176.     
  177.   // Allocate Client Characteristic Configuration table  
  178.   GUAProfile_Char1_Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *  
  179.                                                             linkDBNumConns );  
  180.   if ( GUAProfile_Char1_Config == NULL )  
  181.   {       
  182.     return ( bleMemAllocError );  
  183.   }  
  184.     
  185.   // Initialize Client Characteristic Configuration attributes    
  186.   GATTServApp_InitCharCfg( INVALID_CONNHANDLE, GUAProfile_Char1_Config );    
  187.       
  188.       
  189.   if ( services & GUAPROFILE_SERVICE )    
  190.   {    
  191.     // Register GATT attribute list and CBs with GATT Server App    
  192.     status = GATTServApp_RegisterService( GUAProfileAttrTbl,     
  193.                                           GATT_NUM_ATTRS( GUAProfileAttrTbl ),   
  194.                                           GATT_MAX_ENCRYPT_KEY_SIZE,                                            
  195.                                           &GUAProfileCBs );    
  196.   }    
  197.     
  198.   return ( status );    
  199. }    
  200.     
  201. /*********************************************************************  
  202.  * @fn      GUAProfile_RegisterAppCBs  
  203.  *  
  204.  * @brief   Registers the application callback function. Only call   
  205.  *          this function once.  
  206.  *  
  207.  * @param   callbacks - pointer to application callbacks.  
  208.  *  
  209.  * @return  SUCCESS or bleAlreadyInRequestedMode  
  210.  */    
  211. bStatus_t GUAProfile_RegisterAppCBs( GUAProfileCBs_t *appCallbacks )    
  212. {    
  213.   if ( appCallbacks )    
  214.   {    
  215.     GUAProfile_AppCBs = appCallbacks;    
  216.         
  217.     return ( SUCCESS );    
  218.   }    
  219.   else    
  220.   {    
  221.     return ( bleAlreadyInRequestedMode );    
  222.   }    
  223. }    
  224.     
  225. /*********************************************************************  
  226.  * @fn      GUAProfile_SetParameter  
  227.  *  
  228.  * @brief   Set a GUA Profile parameter.  
  229.  *  
  230.  * @param   param - Profile parameter ID  
  231.  * @param   len - length of data to right  
  232.  * @param   pValue - pointer to data to write.  This is dependent on  
  233.  *          the parameter ID and WILL be cast to the appropriate   
  234.  *          data type (example: data type of uint16 will be cast to   
  235.  *          uint16 pointer).  
  236.  *  
  237.  * @return  bStatus_t  
  238.  */    
  239. bStatus_t GUAProfile_SetParameter( uint8 param, uint8 len, void *pValue )    
  240. {    
  241.   bStatus_t ret = SUCCESS;    
  242.   switch ( param )    
  243.   {    
  244.     case GUAPROFILE_CHAR1:    
  245.       if ( len == GUAPROFILE_CHAR1_LEN )     
  246.       {    
  247.         VOID memcpy( GUAProfile_Char1, pValue, GUAPROFILE_CHAR1_LEN );    
  248.       }    
  249.       else    
  250.       {    
  251.         ret = bleInvalidRange;    
  252.       }    
  253.       break;    
  254.         
  255.     default:    
  256.       ret = INVALIDPARAMETER;    
  257.       break;    
  258.   }    
  259.       
  260.   return ( ret );    
  261. }    
  262.     
  263. /*********************************************************************  
  264.  * @fn      GUAProfile_GetParameter  
  265.  *  
  266.  * @brief   Get a GUA Profile parameter.  
  267.  *  
  268.  * @param   param - Profile parameter ID  
  269.  * @param   pValue - pointer to data to put.  This is dependent on  
  270.  *          the parameter ID and WILL be cast to the appropriate   
  271.  *          data type (example: data type of uint16 will be cast to   
  272.  *          uint16 pointer).  
  273.  *  
  274.  * @return  bStatus_t  
  275.  */    
  276. bStatus_t GUAProfile_GetParameter( uint8 param, void *pValue )    
  277. {    
  278.   bStatus_t ret = SUCCESS;    
  279.   switch ( param )    
  280.   {    
  281.     case GUAPROFILE_CHAR1:    
  282.       VOID memcpy( pValue, GUAProfile_Char1, GUAPROFILE_CHAR1_LEN );    
  283.       break;    
  284.           
  285.     default:    
  286.       ret = INVALIDPARAMETER;    
  287.       break;    
  288.   }    
  289.       
  290.   return ( ret );    
  291. }    
  292.     
  293. /*********************************************************************  
  294.  * @fn          GUAProfile_ReadAttrCB  
  295.  *  
  296.  * @brief       Read an attribute.  
  297.  *  
  298.  * @param       connHandle - connection message was received on  
  299.  * @param       pAttr - pointer to attribute  
  300.  * @param       pValue - pointer to data to be read  
  301.  * @param       pLen - length of data to be read  
  302.  * @param       offset - offset of the first octet to be read  
  303.  * @param       maxLen - maximum length of data to be read  
  304.  *  
  305.  * @return      Success or Failure  
  306.  */    
  307. static uint8 GUAProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,     
  308.                             uint8 *pValue, uint16 *pLen, uint16 offset, uint16 maxLen, uint8_t method )    
  309. {    
  310.   bStatus_t status = SUCCESS;    
  311.      
  312.   // If attribute permissions require authorization to read, return error    
  313.   if ( gattPermitAuthorRead( pAttr->permissions ) )    
  314.   {    
  315.     // Insufficient authorization    
  316.     return ( ATT_ERR_INSUFFICIENT_AUTHOR );    
  317.   }    
  318.       
  319.   // Make sure it's not a blob operation (no attributes in the profile are long    
  320.   if ( offset > 0 )    
  321.   {    
  322.     return ( ATT_ERR_ATTR_NOT_LONG );    
  323.   }    
  324.      
  325.   if ( pAttr->type.len == ATT_BT_UUID_SIZE )    
  326.   {    
  327.     // 16-bit UUID    
  328.     uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);    
  329.     switch ( uuid )    
  330.     {    
  331.       // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;    
  332.       // gattserverapp handles this type for reads    
  333.     
  334.       // GUA characteristic does not have read permissions, but because it    
  335.       //   can be sent as a notification, it must be included here    
  336.       case GUAPROFILE_CHAR1_UUID:    
  337.         *pLen = GUAPROFILE_CHAR1_LEN;    
  338.         VOID memcpy( pValue, pAttr->pValue, GUAPROFILE_CHAR1_LEN );    
  339.         break;    
  340.     
  341.       default:    
  342.         // Should never get here!    
  343.         *pLen = 0;    
  344.         status = ATT_ERR_ATTR_NOT_FOUND;    
  345.         break;    
  346.     }    
  347.   }    
  348.   else    
  349.   {    
  350.     // 128-bit UUID    
  351.     *pLen = 0;    
  352.     status = ATT_ERR_INVALID_HANDLE;    
  353.   }    
  354.     
  355.   return ( status );    
  356. }    
  357.     
  358. /*********************************************************************  
  359.  * @fn      GUAProfile_WriteAttrCB  
  360.  *  
  361.  * @brief   Validate attribute data prior to a write operation  
  362.  *  
  363.  * @param   connHandle - connection message was received on  
  364.  * @param   pAttr - pointer to attribute  
  365.  * @param   pValue - pointer to data to be written  
  366.  * @param   len - length of data  
  367.  * @param   offset - offset of the first octet to be written  
  368.  *  
  369.  * @return  Success or Failure  
  370.  */    
  371. static bStatus_t GUAProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,    
  372.                                  uint8 *pValue, uint16 len, uint16 offset, uint8_t method )    
  373. {    
  374.   bStatus_t status = SUCCESS;    
  375.   uint8 notifyApp = 0xFF;    
  376.       
  377.   // If attribute permissions require authorization to write, return error    
  378.   if ( gattPermitAuthorWrite( pAttr->permissions ) )    
  379.   {    
  380.     // Insufficient authorization    
  381.     return ( ATT_ERR_INSUFFICIENT_AUTHOR );    
  382.   }    
  383.       
  384.   if ( pAttr->type.len == ATT_BT_UUID_SIZE )    
  385.   {    
  386.     // 16-bit UUID    
  387.     uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);    
  388.     switch ( uuid )    
  389.     {    
  390.       case GUAPROFILE_CHAR1_UUID:      
  391.     
  392.         if ( offset == 0 )      
  393.         {      
  394.           if ( len != GUAPROFILE_CHAR1_LEN )      
  395.           {      
  396.             status = ATT_ERR_INVALID_VALUE_SIZE;      
  397.           }      
  398.         }      
  399.         else      
  400.         {      
  401.           status = ATT_ERR_ATTR_NOT_LONG;      
  402.         }      
  403.               
  404.         //将接收到的数据写进特征值中,并且置标志位     
  405.         if ( status == SUCCESS )      
  406.         {      
  407.           VOID memcpy( pAttr->pValue, pValue, GUAPROFILE_CHAR1_LEN );      
  408.           notifyApp = GUAPROFILE_CHAR1;      
  409.         }      
  410.                  
  411.       break;      
  412.           
  413.       case GATT_CLIENT_CHAR_CFG_UUID:    
  414.         //char1通道,则打开notify开关    
  415.         if ( pAttr->handle == GUAProfileAttrTbl[ATTRTBL_GUA_CHAR1_CCC_IDX].handle )//GUA CHAR1 NOTIFY      
  416.         {      
  417.           status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,      
  418.                                                    offset, GATT_CLIENT_CFG_NOTIFY );      
  419.         }                 
  420.         else      
  421.         {      
  422.           status = ATT_ERR_INVALID_HANDLE;      
  423.         }      
  424.         break;    
  425.            
  426.       default:    
  427.         status = ATT_ERR_ATTR_NOT_FOUND;    
  428.         break;    
  429.     }    
  430.   }    
  431.   else    
  432.   {    
  433.     // 128-bit UUID    
  434.     status = ATT_ERR_INVALID_HANDLE;    
  435.   }    
  436.     
  437.   // If a charactersitic value changed then callback function to notify application of change    
  438.   if ( (notifyApp != 0xFF ) && GUAProfile_AppCBs && GUAProfile_AppCBs->pfnGUAProfileChange )    
  439.   {    
  440.     GUAProfile_AppCBs->pfnGUAProfileChange( notifyApp );      
  441.   }     
  442.       
  443.   return ( status );    
  444. }    
  445.       
  446. //******************************************************************************              
  447. //name:             GUAprofile_Notify             
  448. //introduce:        notify发送函数            
  449. //parameter:        param:特征值通道参数    
  450. //                  connHandle:连接句柄        
  451. //                  cpValue:要通知的数据,范围为0~SIMPLEPROFILE_CHAR6,最多20个字节    
  452. //return:           none           
  453. //author:           甜甜的大香瓜                   
  454. //email:            [email protected]       
  455. //QQ group          香瓜BLE之CC2640(557278427)                    
  456. //changetime:       2016.08.27                      
  457. //******************************************************************************     
  458. void GUAprofile_Notify( uint8 param, uint16 connHandle, uint8 *pValue, uint8 len)      
  459. {      
  460.   attHandleValueNoti_t  noti;      
  461.   uint16 value;      
  462.       
  463.   switch ( param )    
  464.   {    
  465.     //特征值1  
  466.     case GUAPROFILE_CHAR1:      
  467.     {  
  468.       //读出CCC  
  469.       value  = GATTServApp_ReadCharCfg( connHandle, GUAProfile_Char1_Config );     
  470.           
  471.       //判断CCC是否被打开  
  472.       if ( value & GATT_CLIENT_CFG_NOTIFY )                                       
  473.       {      
  474.         //分配发送数据缓冲区  
  475.         noti.pValue = GATT_bm_alloc(connHandle, ATT_HANDLE_VALUE_NOTI, GUAPROFILE_CHAR1_LEN, NULL);   
  476.           
  477.         //分配成功,则发送数据  
  478.         if(noti.pValue != NULL)  
  479.         {  
  480.           //填充数据  
  481.           noti.handle = GUAProfileAttrTbl[ATTRTBL_GUA_CHAR1_IDX].handle;      
  482.           noti.len = len;      
  483.           memcpy( noti.pValue, pValue, len);    
  484.             
  485.           //发送数据  
  486.           if (GATT_Notification(connHandle, &noti, FALSE) != SUCCESS)  
  487.           {  
  488.             GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);  
  489.           }  
  490.         }  
  491.       }      
  492.       break;        
  493.     }   
  494.     
  495.     default:    
  496.       break;    
  497.   }          
  498. }      

2)写一个服务头文件GUA_Profile.h(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)

[cpp]  view plain  copy
  1. //******************************************************************************        
  2. //name:         GUA_profile.h        
  3. //introduce:    香瓜自定义的服务,内含一个可读、可写、可通知的特征值    
  4. //author:       甜甜的大香瓜      
  5. //email:        [email protected]       
  6. //QQ group      香瓜BLE之CC2640(557278427)     
  7. //changetime:   2016.08.27     
  8. //******************************************************************************     
  9. #ifndef GUA_PROFILE_H    
  10. #define GUA_PROFILE_H    
  11.     
  12. #ifdef __cplusplus    
  13. extern "C"    
  14. {    
  15. #endif    
  16.     
  17. /*********************************************************************    
  18.  * INCLUDES    
  19.  */    
  20.     
  21. /*********************************************************************  
  22.  * CONSTANTS  
  23.  */    
  24.     
  25. // Profile Parameters    
  26. #define GUAPROFILE_CHAR1                       0  // RW uint8 - Profile GUA Characteristic 1 value    
  27.      
  28. // GUA Service UUID    
  29. #define GUAPROFILE_SERV_UUID                   0xFFE0    
  30.         
  31. // GUA CHAR1 UUID    
  32. #define GUAPROFILE_CHAR1_UUID                  0xFFE1    
  33.     
  34. // GUA Profile Services bit fields    
  35. #define GUAPROFILE_SERVICE                     0x00000001    
  36.     
  37. // Length of GUA Characteristic 1 in bytes    
  38. #define GUAPROFILE_CHAR1_LEN                   20      
  39. /*********************************************************************  
  40.  * TYPEDEFS  
  41.  */    
  42.     
  43.       
  44.       
  45. /*********************************************************************  
  46.  * MACROS  
  47.  */    
  48.     
  49. /*********************************************************************  
  50.  * Profile Callbacks  
  51.  */    
  52. // Callback when a characteristic value has changed    
  53. typedef void (*GUAProfileChange_t)( uint8 paramID );    
  54.     
  55. typedef struct    
  56. {    
  57.   GUAProfileChange_t        pfnGUAProfileChange;  // Called when characteristic value changes    
  58. } GUAProfileCBs_t;    
  59.     
  60. /*********************************************************************  
  61.  * API FUNCTIONS   
  62.  */    
  63.     
  64. /*  
  65.  * GUAProfile_AddService- Initializes the GUA service by registering  
  66.  *          GATT attributes with the GATT server.  
  67.  *  
  68.  * @param   services - services to add. This is a bit map and can  
  69.  *                     contain more than one service.  
  70.  */    
  71.     
  72. extern bStatus_t GUAProfile_AddService( uint32 services );    
  73.       
  74. /*  
  75.  * GUAProfile_RegisterAppCBs - Registers the application callback function.  
  76.  *                    Only call this function once.  
  77.  *  
  78.  *    appCallbacks - pointer to application callbacks.  
  79.  */    
  80. extern bStatus_t GUAProfile_RegisterAppCBs( GUAProfileCBs_t *appCallbacks );    
  81.     
  82. /*  
  83.  * GUAProfile_SetParameter - Set a Simple Key Profile parameter.  
  84.  *  
  85.  *    param - Profile parameter ID  
  86.  *    len - length of data to right  
  87.  *    pValue - pointer to data to write.  This is dependent on  
  88.  *          the parameter ID and WILL be cast to the appropriate   
  89.  *          data type (example: data type of uint16 will be cast to   
  90.  *          uint16 pointer).  
  91.  */    
  92. extern bStatus_t GUAProfile_SetParameter( uint8 param, uint8 len, void *pValue );    
  93.       
  94. /*  
  95.  * GUA_GetParameter - Get a Simple Key Profile parameter.  
  96.  *  
  97.  *    param - Profile parameter ID  
  98.  *    pValue - pointer to data to write.  This is dependent on  
  99.  *          the parameter ID and WILL be cast to the appropriate   
  100.  *          data type (example: data type of uint16 will be cast to   
  101.  *          uint16 pointer).  
  102.  */    
  103. extern bStatus_t GUAProfile_GetParameter( uint8 param, void *pValue );    
  104.     
  105. //******************************************************************************              
  106. //name:             GUAprofile_Notify             
  107. //introduce:        notify发送函数            
  108. //parameter:        param:特征值通道参数    
  109. //                  connHandle:连接句柄        
  110. //                  cpValue:要通知的数据,范围为0~SIMPLEPROFILE_CHAR6,最多20个字节    
  111. //return:           none           
  112. //author:           甜甜的大香瓜                   
  113. //email:            [email protected]       
  114. //QQ group          香瓜BLE之CC2640(557278427)                    
  115. //changetime:       2016.08.27                         
  116. extern void GUAprofile_Notify( uint8 param, uint16 connHandle, uint8 *pValue, uint8 len);    
  117. /*********************************************************************    
  118. *********************************************************************/    
  119.     
  120. #ifdef __cplusplus    
  121. }    
  122. #endif    
  123.     
  124. #endif /* GUA_PROFILE_H */    

3)工程中添加GUA_Profile.c和GUA_Profile.h



4)在IAR设置中添加服务的文件路径

[cpp]  view plain  copy
  1. $PROJ_DIR$/../../../Source/Application/GUA      

2、在应用层中添加服务相关的代码

1)添加GUA_Profile头文件(SimpleBLEPeripheral.c中)

[cpp]  view plain  copy
  1. //香瓜    
  2. #include "GUA_Profile.h"       
  3. //香瓜  

2)服务初始化(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)

[cpp]  view plain  copy
  1. //香瓜    
  2.   //增加服务    
  3.   GUAProfile_AddService(GATT_ALL_SERVICES);    
  4.     
  5.   //初始化特征值    
  6.   uint8 GUAProfile_Char1Value[GUAPROFILE_CHAR1_LEN] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};    
  7.   GUAProfile_SetParameter( GUAPROFILE_CHAR1, GUAPROFILE_CHAR1_LEN, &GUAProfile_Char1Value );    
  8.     
  9.   //添加回调函数    
  10.   VOID GUAProfile_RegisterAppCBs( &simpleBLEPeripheral_GUAProfileCBs );        
  11. //香瓜    

3)定义服务的回调函数及处理函数(SimpleBLEPeripheral.c中)

[cpp]  view plain  copy
  1. //******************************************************************************              
  2. //name:             GUAProfileChangeCB             
  3. //introduce:        应用层香瓜服务回调函数           
  4. //parameter:        paramID:特征值ID                    
  5. //return:           none           
  6. //author:           甜甜的大香瓜                   
  7. //email:            [email protected]       
  8. //QQ group          香瓜BLE之CC2640(557278427)                    
  9. //changetime:       2016.08.27                       
  10. //******************************************************************************   
  11. static void GUAProfileChangeCB( uint8 paramID )    
  12. {  
  13.   SimpleBLEPeripheral_enqueueMsg(SBP_GUA_CHAR_CHANGE_EVT, paramID);  
  14. }  
  15.   
  16. //******************************************************************************              
  17. //name:             GUA_CharValueChangeEvt             
  18. //introduce:        应用层香瓜服务的处理函数           
  19. //parameter:        paramID:特征值ID                    
  20. //return:           none           
  21. //author:           甜甜的大香瓜                   
  22. //email:            [email protected]       
  23. //QQ group          香瓜BLE之CC2640(557278427)                    
  24. //changetime:       2016.08.27                       
  25. //******************************************************************************   
  26. static void GUA_CharValueChangeEvt(uint8_t paramID)  
  27. {    
  28.   uint16 notify_Handle;       
  29.   uint8 bBuf[20] = {0};     
  30.   uint8 *p = bBuf;    
  31.         
  32.   switch( paramID )    
  33.   {    
  34.     case GUAPROFILE_CHAR1:       
  35.             
  36.       GAPRole_GetParameter( GAPROLE_CONNHANDLE, &notify_Handle);        //获取Connection Handle       
  37.             
  38.       for(uint8 i = 0; i < 20; i++)                                     //写一个20字节的测试缓冲区的数据      
  39.       {      
  40.         *(p+i) = i;      
  41.       }      
  42.         
  43.       GUAprofile_Notify(GUAPROFILE_CHAR1, notify_Handle, p, 20);          
  44.     
  45.       break;    
  46.     
  47.     default:    
  48.       // should not reach here!    
  49.       break;    
  50.   }    
  51. }    
里面添加了测试代码,一旦接收到数据,就把0~19发给主机。


4)声明服务的回调函数和处理函数(SimpleBLEPeripheral.c中)

[cpp]  view plain  copy
  1. //香瓜    
  2. static void GUAProfileChangeCB( uint8 paramID );    
  3. static void GUA_CharValueChangeEvt(uint8_t paramID);  
  4. //香瓜  

5)注册回调函数(SimpleBLEPeripheral.c中)

[cpp]  view plain  copy
  1. //香瓜    
  2. // GUA Profile Callbacks    
  3. static GUAProfileCBs_t simpleBLEPeripheral_GUAProfileCBs =    
  4. {    
  5.   GUAProfileChangeCB    // Charactersitic value change callback    
  6. };    
  7. //香瓜   

6)添加香瓜服务处理事件(SimpleBLEPeripheral.c中)

①添加香瓜服务处理事件的宏定义

[cpp]  view plain  copy
  1. #define SBP_GUA_CHAR_CHANGE_EVT               0x0010  

②添加香瓜服务处理事件的处理部分(替换SimpleBLEPeripheral.c中的SimpleBLEPeripheral_processAppMsg函数

[cpp]  view plain  copy
  1. static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)  
  2. {  
  3.   switch (pMsg->hdr.event)  
  4.   {  
  5.     case SBP_STATE_CHANGE_EVT:  
  6.       SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->  
  7.                                                 hdr.state);  
  8.       break;  
  9.   
  10.     case SBP_CHAR_CHANGE_EVT:  
  11.       SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);  
  12.       break;  
  13.   
  14.     case SBP_GUA_CHAR_CHANGE_EVT:  
  15.       GUA_CharValueChangeEvt(pMsg->hdr.state);  
  16.       break;  
  17.         
  18.     default:  
  19.       // Do nothing.  
  20.       break;  
  21.   }  
  22. }  

七、注意事项

手机可能缓存了之前的代码(在更新过CC2541的代码之后,都需要清除手机端的缓存!!!),因此要清除缓存,清除缓存的方法如下:

方法一:关闭app、关闭蓝牙总开关、打开蓝牙总开关、打开app。
方法二:手机重启。


八、实验结果

注:香瓜在开发CC2541时常用的truthblue在读取特征值时会出错,比如char1(0x01)却读到7、8个字节的乱数据,暂用蓝牙读写器代替。




可见上图实现了使用香瓜服务中的特征值进行的收发,因此本文步骤实验成功。

猜你喜欢

转载自blog.csdn.net/wukery/article/details/78620768