首先要指出,字段属性有notify的不能同时有read,write属性,别问哥,哥也不知道,反正我做的就不能notify,只能read,write。

分享的程序段第一字段有notify属性,第二字段read,write属性。

费话少说,看代码,H文件:

#ifndef LOCKER_H
#define LOCKER_H #ifdef __cplusplus
extern "C"
{
#endif #define SERVAPP_NUM_ATTR_SUPPORTED (1+4+3) // Simple Profile Service UUID
#define LOCKERPROFILE_SERV_UUID 0xFFF0 #define LOCKERPROFILE_NOTIFY_UUID 0xFFF1
#define LOCKERPROFILE_NOTIFY_MAX_LEN 5 #define LOCKERPROFILE_STREAM_UUID 0xFFF2
#define LOCKERPROFILE_STREAM_MAX_LEN 5 #define SIMPLEPROFILE_SERVICE 0x00000001
/*********************************************************************
* Profile Callbacks
*/
// Callback when a characteristic value has changed
typedef void (*app_input_cb_t)( uint16 uuid ,uint8 *pdata, int len); /*********************************************************************
* lockerProfile_AddService- Initializes the Simple GATT Profile service by registering
* GATT attributes with the GATT server.
* @param services - services to add. This is a bit map and can contain more than one service.
* @param cb - the function will be called, while service receive a message .
* return always return SUCCESS
*/
bStatus_t lockerProfile_AddService( uint32 services ,app_input_cb_t cb);
/*
* lockerProfile_AddService - Set a Simple GATT Profile parameter.
* uuid - which service's uuid as sender target
* len - length of data to right
* value - pointer to data to write. This is dependent on
* the parameter uuid and WILL be cast to the appropriate
* data type .
*/
bStatus_t locker_send( uint16 uuid,void *pdata , uint8 len);
/*
* locker_Read - Get a Simple GATT Profile parameter by uuid.
* param - Profile uuid
* value - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type .
* return : return data length, if op' failse it'll return -1;
*/
int locker_Read( uint16 uuid, void *pdata ); #ifdef __cplusplus
}
#endif #endif /* SIMPLEGATTPROFILE_H */

  C文件:

/*********************************************************************
* INCLUDES
*/
#include "bcomdef.h"
#include "OSAL.h"
#include "linkdb.h"
#include "att.h"
#include "gatt.h"
#include "gatt_uuid.h"
#include "gattservapp.h"
#include "gapbondmgr.h" #include "locker.h"
#include "stdio.h" /*********************************************************************
* GLOBAL VARIABLES
*/
// Simple GATT Profile Service UUID: 0xFFF0
CONST uint8 lockerSvrUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(LOCKERPROFILE_SERV_UUID),
HI_UINT16(LOCKERPROFILE_SERV_UUID)
};
// notify UUID: 0xFFF1
CONST uint8 lockerNotifyUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(LOCKERPROFILE_NOTIFY_UUID),
HI_UINT16(LOCKERPROFILE_NOTIFY_UUID)
};
// stream UUID: 0xFFF2
CONST uint8 lockerStreamUUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(LOCKERPROFILE_STREAM_UUID),
HI_UINT16(LOCKERPROFILE_STREAM_UUID)
};
/*********************************************************************
* LOCAL VARIABLES
*/
static app_input_cb_t app_input_cb = NULL;
/*********************************************************************
* Profile Attributes - variables
*/
// locker Profile Service attribute
static CONST gattAttrType_t lockerProfileService = { ATT_BT_UUID_SIZE, lockerSvrUUID }; // locker Profile Notify Properties
static uint8 lockerNotifyProps = GATT_PROP_NOTIFY;
static uint8 lockerNotifyStream[LOCKERPROFILE_NOTIFY_MAX_LEN];
static uint8 lockerNotifyDesp[17] = "notify\0";
static gattCharCfg_t lockerNotifyConfig[GATT_MAX_NUM_CONN]; // locker Profile Stream Properties
static uint8 lockerStreamProps = GATT_PROP_READ | GATT_PROP_WRITE;
static uint8 lockerStream[LOCKERPROFILE_STREAM_MAX_LEN];
static uint8 lockerStreamDesp[17] = "stream\0";
/*********************************************************************
* Profile Attributes - Table
*/ static gattAttribute_t LockerProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
// Simple Profile Service
{
{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&lockerProfileService /* pValue */
},
/**************notify attribute**********************/
// notify Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&lockerNotifyProps
},
// notify stream buffer
{
{ ATT_BT_UUID_SIZE, lockerNotifyUUID },
0,
0,
lockerNotifyStream
},
// notify stream configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)lockerNotifyConfig
},
// notify stream Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
lockerNotifyDesp
},
/************************stream buffer attribute***********************/
// stream Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&lockerStreamProps
},
// stream buffer
{
{ ATT_BT_UUID_SIZE, lockerStreamUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
lockerStream
},
// stream Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
lockerStreamDesp
},
}; /*********************************************************************
* LOCAL FUNCTIONS
*/
static uint8 lockerReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
static bStatus_t lockerWriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset ); static void lockerHandleConnStatusCB( uint16 connHandle, uint8 changeType ); /*********************************************************************
* PROFILE CALLBACKS
*/
// Simple Profile Service Callbacks
CONST gattServiceCBs_t lockerProfileCBs =
{
lockerReadAttrCB, // Read callback function pointer
lockerWriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
}; bStatus_t lockerProfile_AddService( uint32 services ,app_input_cb_t cb)
{
uint8 status = SUCCESS;
printf("lockerProfile_AddService: \n");
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, lockerNotifyConfig );
// Register with Link DB to receive link status change callback
VOID linkDB_Register( lockerHandleConnStatusCB );
if ( services & SIMPLEPROFILE_SERVICE )
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( LockerProfileAttrTbl,
GATT_NUM_ATTRS( LockerProfileAttrTbl ),
&lockerProfileCBs );
}
app_input_cb = cb;
return ( status );
}
bStatus_t locker_send( uint16 uuid,void *pdata , uint8 len)
{
bStatus_t ret = SUCCESS; switch ( uuid )
{
case LOCKERPROFILE_NOTIFY_UUID:
if ( len <= LOCKERPROFILE_NOTIFY_MAX_LEN)
{
printf("locker_send: uuid:%04x notify app \n",uuid);
osal_memcpy(lockerNotifyStream,pdata,len);
GATTServApp_ProcessCharCfg(lockerNotifyConfig,lockerNotifyStream, FALSE,
LockerProfileAttrTbl, GATT_NUM_ATTRS( LockerProfileAttrTbl ),
INVALID_TASK_ID );
}
else
{
ret = bleInvalidRange;
}
break;
case LOCKERPROFILE_STREAM_UUID:
if ( len <= LOCKERPROFILE_STREAM_MAX_LEN)
{
printf("locker_Send: uuid:%04x write to stream buffer and waite to read \n",uuid);
osal_memcpy(lockerStream,pdata,len);
}
else
{
ret = bleInvalidRange;
}
default:
ret = INVALIDPARAMETER;
break;
}
return ( ret );
} int locker_Read( uint16 uuid, void *pdata )
{
int ret;
printf("locker_Read: uuid:%04x \n",uuid);
switch ( uuid )
{
case LOCKERPROFILE_NOTIFY_UUID:
osal_memcpy(pdata,lockerNotifyStream,LOCKERPROFILE_NOTIFY_MAX_LEN);
ret = LOCKERPROFILE_NOTIFY_MAX_LEN;
break;
case LOCKERPROFILE_STREAM_UUID:
osal_memcpy(pdata,lockerStream,LOCKERPROFILE_STREAM_MAX_LEN);
ret = LOCKERPROFILE_NOTIFY_MAX_LEN;
break;
default:
ret = -1;
break;
}
return ( ret );
} static uint8 lockerReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
{
bStatus_t status = SUCCESS; // If attribute permissions require authorization to read, return error
if ( gattPermitAuthorRead( pAttr->permissions ) )
{
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
} // Make sure it's not a blob operation (no attributes in the profile are long)
if ( offset > 0 )
{
return ( ATT_ERR_ATTR_NOT_LONG );
} if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
printf("lockerProfile_ReadAttrCB: uuid:%04x \n",uuid);
switch ( uuid )
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
// characteristics 1 and 2 have read permissions
// can be sent as a notification, it is included here
case LOCKERPROFILE_NOTIFY_UUID:
*pLen = LOCKERPROFILE_NOTIFY_MAX_LEN;
osal_memcpy(pValue,pAttr->pValue,LOCKERPROFILE_NOTIFY_MAX_LEN);
break;
case LOCKERPROFILE_STREAM_UUID:
*pLen = LOCKERPROFILE_STREAM_MAX_LEN;
osal_memcpy(pValue,pAttr->pValue,LOCKERPROFILE_STREAM_MAX_LEN);
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
} return ( status );
} static bStatus_t lockerWriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset )
{
bStatus_t status = SUCCESS;
// If attribute permissions require authorization to write, return error
if ( gattPermitAuthorWrite( pAttr->permissions ) )
{
// Insufficient authorization
return ( ATT_ERR_INSUFFICIENT_AUTHOR );
} if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
printf("lockerProfile_WriteAttrCB: uuid:%04x \n",uuid);
switch ( uuid )
{
case LOCKERPROFILE_NOTIFY_UUID:
status = ATT_ERR_INVALID_HANDLE;
//Write the value
break;
case LOCKERPROFILE_STREAM_UUID:
if((offset==0)&(app_input_cb!=NULL))
{
if(len<=LOCKERPROFILE_STREAM_MAX_LEN)
osal_memcpy(lockerStream,pValue,len);
app_input_cb(LOCKERPROFILE_STREAM_UUID,pValue,len);
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY );
break;
default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}
return ( status );
}
static void lockerHandleConnStatusCB( uint16 connHandle, uint8 changeType )
{
// Make sure this is not loopback connection
if ( connHandle != LOOPBACK_CONNHANDLE )
{
// Reset Client Char Config if connection has dropped
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
( !linkDB_Up( connHandle ) ) ) )
{
printf("lockerProfile_HandleConnStatusCB: Reset Client Char Config if connection has dropped \n");
GATTServApp_InitCharCfg( connHandle, lockerNotifyConfig );
}
}
} /*********************************************************************
*********************************************************************/

  在simpleBLEPeripheral.c下增加input函数用于接收数据:

void input(uint16 uuid, uint8 *pdata , int  len)
{
int i;
printf("input from uuid: %04x len:%d data:",uuid,len);
for(i=0;i<len;i++)
printf("%02x ",pdata[i]);
printf("\n");
}

  初始化时:

void SimpleBLEPeripheral_Init( uint8 task_id )
{
simpleBLEPeripheral_TaskID = task_id; // Setup the GAP
VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL ); // Setup the GAP Peripheral Role Profile
{
uint8 initial_advertising_enable = TRUE;
// By setting this to zero, the device will go into the waiting state after
// being discoverable for 30.72 second, and will not being advertising again
// until the enabler is set back to TRUE
uint16 gapRole_AdvertOffTime = 0; uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; // Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
} // Set the GAP Characteristics
GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName ); // Set advertising interval
{
uint16 advInt = DEFAULT_ADVERTISING_INTERVAL; GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
} // Setup the GAP Bond Manager
{
uint32 passkey = 0; // passkey "000000"
uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8 mitm = TRUE;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8 bonding = TRUE;
GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
} // Initialize GATT attributes
GGS_AddService( GATT_ALL_SERVICES ); // GAP
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
DevInfo_AddService(); // Device Information Service
lockerProfile_AddService( GATT_ALL_SERVICES,input); // Simple GATT Profile // Register for all key events - This app will handle all key events
RegisterForKeys( simpleBLEPeripheral_TaskID );
// Enable clock divide on halt
// This reduces active current while radio is active and CC254x MCU
// is halted
HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT ); // Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT ); }

  good luck!!我的已经工作的,你的呢?

CC2540自己的配置文件的更多相关文章

  1. 蓝牙协议 基于TI cc2540 模块的理解(转)

    源:蓝牙协议 基于TI cc2540 模块的理解 Bluetooth 4.0开发 Platform:TI IC:cc2540 Environment:windows 7 tools:IAR 8.20. ...

  2. Ti CC2540蓝牙模块学习笔记整理

    接触CC2540几天,终于有了初步的理解,现将笔记整理如下,只是皮毛,如有错误,还请指正,还有好多没闹明白的地方,以后应该还会继续向里面更新~ 一.整体 1.TI的蓝牙平台支持2种协议栈/应用配置:单 ...

  3. .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整(续)-使用配置文件动态注入

    上次实现了依赖注入,但是web项目必须要引用业务逻辑层和数据存储层的实现,项目解耦并不完全:另一方面,要同时注入业务逻辑层和数据访问层,注入的服务直接写在Startup中显得非常臃肿.理想的方式是,w ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-补充WebApi与Unity注入-配置文件

    系列目录 上一篇演示了WebApi利用Unity注入 很多人问我如何用配置文件来配置注入,本节演示如何利用配置文件来注入,道理是一样的,跳转到上一节下载源码一起来动手! 1.打开源码定位到文件Depe ...

  5. Spring配置文件标签报错:The prefix "XXX" for element "XXX:XXX" is not bound. .

    例如:The prefix "context" for element "context:annotation-config" is not bound. 这种 ...

  6. nginx服务器安装及配置文件详解

    nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和nginx.conf配置选项的说明,留作以后参考.像负载均衡配置(包括健康检查).缓存( ...

  7. C#开发中使用配置文件对象简化配置的本地保存

    C#开发中使用配置文件对象简化配置的本地保存 0x00 起因 程序的核心是数据和逻辑,开发过程中免不了要对操作的数据进行设置,而有些数据在程序执行过程中被用户或程序做出的修改是应该保存下来的,这样程序 ...

  8. 使用T4模板生成不同部署环境下的配置文件

    在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据目标环境不同而不同.比如在开发环境中,数据 ...

  9. 配置文件Java读写

    今天把配置文件的Bug修复了,总结一下Java配置文件如何读写 配置文件的格式 以.properties后缀结尾,内容不出现空格和双引号 //config.properties Driver=com. ...

随机推荐

  1. javascipt的【函数表达式】

    函数表达式 在编程时,我们可以看到不管是什么类库,jquery也好,zepto也好,都会用到大量的命名函数和匿名函数表达式,本节点就是为了弄懂为何会有这些函数表达式,以及在什么情况下会使用到这些表达式 ...

  2. consolel API大全-附测试结果

    f 简介: JS中默认没有console对象, 这是某些浏览器提供的浏览器内置对象, 低版本IE就没有, 其他主流浏览器应该都有.它能看到结构话的东西,如果是alert,淡出一个对象就是[object ...

  3. 启动 Eclipse 弹出“Failed to load the JNI shared library jvm.dll”错误的解决方法

    原因1:给定目录下jvm.dll不存在. 对策:(1)重新安装jre或者jdk并配置好环境变量.(2)copy一个jvm.dll放在该目录下. 原因2:eclipse的版本与jre或者jdk版本不一致 ...

  4. C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

    一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...

  5. spring context上下文(应用上下文webApplicationContext)(转载)

    (此文转载:http://www.cnblogs.com/brolanda/p/4265597.html) 一.先说ServletContext javaee标准规定了,servlet容器需要在应用项 ...

  6. excellent cushioning and also vitality go back with this boot

    The particular manufactured fine mesh higher almost addresses the complete boot. Here is the sort of ...

  7. Linux学习之CentOS(二十)--CentOS6.4下修改MySQL编码方法

    但是当我们在试图对数据库中的数据进行备份或者将sql文件导入到我们的数据库时可能就会碰到编码的问题,在windows下安装mysql时我们可以在安装的时候就选择好整个数据库的编码方式(通常设置成utf ...

  8. 《SQL必知必会》学习笔记(一)

    这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...

  9. ubuntu 14.04 修改网络配置

    修改IP地址: vi /etc/network/interfaces

  10. javascript的console.log用法

    f1.html代码 <iframe id="frame2" name="frame1" src="ww.html"></i ...