主机会运行SCAN来搜寻广播中的设备

运行函数:

GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST );

 /**
* @brief Start a device discovery scan.
*
* Public function defined in central.h.
*/
bStatus_t GAPCentralRole_StartDiscovery( uint8 mode, uint8 activeScan, uint8 whiteList )
{
gapDevDiscReq_t params; params.taskID = gapCentralRoleTaskId;
params.mode = mode;
params.activeScan = activeScan;
params.whiteList = whiteList; return GAP_DeviceDiscoveryRequest( &params );
}

GAPCentralRole_StartDiscovery

最终使用的是API:GAP_DeviceDiscoveryRequest

来看几个参数:DEFAULT_DISCOVERY_MODE

// Discovey mode (limited, general, all)
#define DEFAULT_DISCOVERY_MODE     DEVDISC_MODE_ALL

#define DEVDISC_MODE_NONDISCOVERABLE 0x00 //!< No discoverable setting
#define DEVDISC_MODE_GENERAL 0x01 //!< General Discoverable devices
#define DEVDISC_MODE_LIMITED 0x02 //!< Limited Discoverable devices
#define DEVDISC_MODE_ALL 0x03 //!< Not filtered

// TRUE to use active scan
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE

// TRUE to use white list during discovery
#define DEFAULT_DISCOVERY_WHITE_LIST FALSE

//TRUE to only allow advertisements from devices in the white list.

初始化函数中有些设置:

// Setup Central Profile
{
uint8 scanRes = DEFAULT_MAX_SCAN_RES;
GAPCentralRole_SetParameter ( GAPCENTRALROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
}

// Maximum number of scan responses
#define DEFAULT_MAX_SCAN_RES 8

最大的支持扫描到的器件数,为8

GAP_SetParamValue( TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION );
GAP_SetParamValue( TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION );

// Scan duration in ms
#define DEFAULT_SCAN_DURATION 4000

#define TGAP_GEN_DISC_SCAN 2 //!< Minimum time to perform scanning, when performing General Discovery proc (mSec)
#define TGAP_LIM_DISC_SCAN 3 //!< Minimum time to perform scanning, when performing Limited Discovery proc (mSec)

主机的发现过程,有两个事件:GAP_DEVICE_INFO_EVENT,GAP_DEVICE_DISCOVERY_EVENT

#define GAP_DEVICE_INFO_EVENT                 0x0D //!< Sent during the Device Discovery Process when a device is discovered. This event is sent as an OSAL message defined as gapDeviceInfoEvent_t.

发现当中每发现一个device就触发一次

#define GAP_DEVICE_DISCOVERY_EVENT            0x01 //!< Sent when the Device Discovery Process is complete. This event is sent as an OSAL message defined as gapDevDiscEvent_t.

发现结束时候调用

 case GAP_DEVICE_INFO_EVENT:
{
// if filtering device discovery results based on service UUID
if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )
{
if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID,
pEvent->deviceInfo.pEvtData,
pEvent->deviceInfo.dataLen ) )
{
simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
}
}
}
break;

GAP_DEVICE_INFO_EVENT

每次发现会调用两个函数:simpleBLEFindSvcUuid,确定发现的设备SvcUUid是否匹配,匹配的话调用simpleBLEAddDeviceInfo将其地址加入列表

 /*********************************************************************
* @fn simpleBLEFindSvcUuid
*
* @brief Find a given UUID in an advertiser's service UUID list.
*
* @return TRUE if service UUID found
*/
static bool simpleBLEFindSvcUuid( uint16 uuid, uint8 *pData, uint8 dataLen )
{
uint8 adLen;
uint8 adType;
uint8 *pEnd; pEnd = pData + dataLen - ; // While end of data not reached
while ( pData < pEnd )
{
// Get length of next AD item
adLen = *pData++;
if ( adLen > )
{
adType = *pData; // If AD type is for 16-bit service UUID
if ( adType == GAP_ADTYPE_16BIT_MORE || adType == GAP_ADTYPE_16BIT_COMPLETE )
{
pData++;
adLen--; // For each UUID in list
while ( adLen >= && pData < pEnd )
{
// Check for match
if ( pData[] == LO_UINT16(uuid) && pData[] == HI_UINT16(uuid) )
{
// Match found
return TRUE;
} // Go to next
pData += ;
adLen -= ;
} // Handle possible erroneous extra byte in UUID list
if ( adLen == )
{
pData++;
}
}
else
{
// Go to next item
pData += adLen;
}
}
} // Match not found
return FALSE;
}

simpleBLEFindSvcUuid

这个函数利用广播数据格式来判断,先找到类型字节,判断类型是否是uuid,是的话判断内容,不是的话调到下一段内容,把广播格式再粘一次

 / GAP - Advertisement data (max size =  bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ), };

advertData

如果是的话加入数组当中,也将扫描到的设备数+1

 /*********************************************************************
* @fn simpleBLEAddDeviceInfo
*
* @brief Add a device to the device discovery result list
*
* @return none
*/
static void simpleBLEAddDeviceInfo( uint8 *pAddr, uint8 addrType )
{
uint8 i; // If result count not at max
if ( simpleBLEScanRes < DEFAULT_MAX_SCAN_RES )
{
// Check if device is already in scan results
for ( i = ; i < simpleBLEScanRes; i++ )
{
if ( osal_memcmp( pAddr, simpleBLEDevList[i].addr , B_ADDR_LEN ) )
{
return;
}
} // Add addr to scan result list
osal_memcpy( simpleBLEDevList[simpleBLEScanRes].addr, pAddr, B_ADDR_LEN );
simpleBLEDevList[simpleBLEScanRes].addrType = addrType; // Increment scan result count
simpleBLEScanRes++;
}
}

simpleBLEAddDeviceInfo

发现结束后会将数组转移做些存储然后指示用户下一步

 case GAP_DEVICE_DISCOVERY_EVENT:
{
// discovery complete
simpleBLEScanning = FALSE; // if not filtering device discovery results based on service UUID
if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )
{
// Copy results
simpleBLEScanRes = pEvent->discCmpl.numDevs;
osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,
(sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );
} LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes,
, HAL_LCD_LINE_1 );
if ( simpleBLEScanRes > )
{
LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 );
} // initialize scan index to last device
simpleBLEScanIdx = simpleBLEScanRes; }
break;

GAP_DEVICE_DISCOVERY_EVENT

key里面有个更新显示,对于收到的device比较多的时候:

  if ( keys & HAL_KEY_LEFT )
{
// Display discovery results
if ( !simpleBLEScanning && simpleBLEScanRes > )
{
// Increment index of current result (with wraparound)
simpleBLEScanIdx++;
if ( simpleBLEScanIdx >= simpleBLEScanRes )
{
simpleBLEScanIdx = ;
} LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + ,
, HAL_LCD_LINE_1 );
LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ),
HAL_LCD_LINE_2 );
}
}

HAL_KEY_LEFT

TI BLE:SCAN的更多相关文章

  1. TI BLE协议栈软件框架分析

    看源代码的时候,一般都是从整个代码的入口处开始,TI  BLE 协议栈源码也不例外.它的入口main()函数就是整个程序的入口,由系统上电时自动调用. 它主要做了以下几件事情: (一)底层硬件初始化配 ...

  2. TI BLE: Advertisement

    #define GAPROLE_ADVERT_ENABLED 0x305 //!< Enable/Disable Advertising. Read/Write. Size is uint8. ...

  3. TI BLE STACK - OSAL

    TI 的OSAL做的很不错,不过看起来也挺费劲可能自己水平太差吧,网上买的谷雨的开发板觉得确实挺不错的. 做点学习笔记,首先是记录OSAL里执行的顺序流程,主要是task ,event,message ...

  4. TI BLE CC2541的通讯协议.

    包类型: 01命令/02数据/03应答消息 开始标志FF/本数据包长度(注意是16进制)/校验码/包ID/包类型01: 表示是命令/01表示下面要开始传输/03字符串编号/字符串长度/结束位FEFF  ...

  5. TI BLE CC2541的I2C主模式

    由于要写TM1680, 写命令跟写数据, 所以需要使用CC2541的I2C, 2541是有硬件I2C的. tm1680.c: #include "tm1680.h" //TM168 ...

  6. TI BLE CC2541的SPI主模式

    SPI就是用4条线来串行传输数据, 2541只能用模拟的方式用GPIO来做. //*********************************************************** ...

  7. TI BLE:读本机地址

    uint8 ownAddress[B_ADDR_LEN];  //B_ADDR_LEN=6GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); #def ...

  8. TI BLE : GAP Bond Manager

    // Setup the GAP Bond Manager { uint32 passkey = 0; // passkey "000000" uint8 pairMode = G ...

  9. android ble connect slowly

    Hi I'm writing an Android app to connect to a BLE peripheral device. Android 4.4.2, Galaxy Nexus. I ...

随机推荐

  1. Python之面向对象新式类和经典类

    Python之面向对象新式类和经典类 新式类和经典类的继承原理: 在Python3中,就只有新式类一种了. 先看Python3中新式类: 类是有继承顺序的: Python的类是可以继承多个类的,也就是 ...

  2. jquery 修改input输入框的 readOnly属性 && input输入框隐藏

    html的代码 <div class="control-group"> <label class="control-label required&quo ...

  3. 2017 计蒜之道 初赛 第一场 B阿里天池的新任务(简单)

    题链:"https://nanti.jisuanke.com/t/15500" 本来希望通过找循环节然后套KMP来通过后面题的,可是只过了B题,可能循环节不一定是存在的. #inc ...

  4. this关键字的由来及使用

    Student.java /* * 学生类 * * 起名字我们要求做到见名知意. * * 如果有局部变量名和成员变量名相同,在局部使用的时候,采用的是就近原则. * *我们有没有办法吧局部变量的nam ...

  5. 【codeforces 1109B】Sasha and One More Name

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 如果这个回文串的左半部分,字母全是一样的. 那么显然不可能再分出来了,因为不管怎么分怎么排列,最后肯定都只能和原串一样. 所以无解 其他情况下 ...

  6. spark streaming基于Kafka的开发

    spark streaming使用Kafka数据源进行数据处理,本文侧重讲述实践使用. 一.基于receiver的方式 在使用receiver的时候,如果receiver和partition分配不当, ...

  7. [luoguP1981] 表达式求值(U•ェ•*U)

    传送门 弄两个栈,一个存数,一个存运算符,然后乱搞. 代码 #include <cstdio> #include <cstring> #include <iostream ...

  8. [NOIP2006] 普及组

    明明的随机数 STL真是偷懒神器 /*by SilverN*/ #include<algorithm> #include<iostream> #include<cstri ...

  9. 【CodeChef】KNGHTMOV(方案数DP)

    题意: 考虑一张无限大的方格棋盘.我们有一个“骑士”,它必须从(0,0)格开始,按照如下规则,移动至(X,Y)格:每一步,它只能从(u,v)格移动至(u+Ax,v+Ay)或者(u+Bx,v+By).注 ...

  10. key通用操作【九】

    一.概述: 在该系列的前几篇博客中,主要讲述的是与Redis数据类型相关的命令,如String.List.Set.Hashes和Sorted-Set.这些命令都具有一个共同点,即所有的操作都是针对与K ...