请教BLE 中的windows sever 2003和client角色问题

四、BLE(中) - arduino - 博客园
随笔 - 15, 文章 - 0, 评论 - 0, 引用 - 0
1.1&&&&&& GATT Manager
GATT MGR模块管理所有的GATT服务,同时也是连接GATT模块与GATT ServiceS模块的桥梁。
1.1.1&&& 主要功能模块
先来看一张该模块的API关系图,sink_gatt_manager.c里面定义的接口主要供ApplicationLayer调用和回调,如用户(BLE Server)调用sinkGattManagerStartAdvertising()开始进行广播,用户(BLE Client)调用sinkGattManagerStartConnection()开始进行BLE连接。该该部分同时负责接收和处理来自ApplicationLayer的消息——GATT_MANAGER_DISCONNECT_IND,GATT_MANAGER_REGISTER_WITH_GATT_CFM等GATT_MANAGER_XXX系列消息。这些消息主要用来处理注册连接确认,断开连接请求等事件。
&&&&&& Gatt_nanager_handler.c主要定义和实现了内部回调函数gattManagerMessageHandler(),该接口主要接收来自GATT模块的GATT_XXX系列消息,以及GATT MGR内部的消息GATT_MANAGER_INTERNAL_MSG_XXX。处理这些消息的函数接口主要分布在gatt_manager_server.c和gatt_manager_client.c两个函数内部。
&&&&&& 根据BLE工作的角色不同,BLE分别定义了两套接口,分别完成客户和服务的角色的任务。
&&&&&&&& 作为BLE客户主要完成的任务有:
1.连接到服务器。这里包括主导发起连接至服务器,以及接收到服务器连接请求的确认。即:GattManagerConnectToRemoteServer()用来主动发起连接请求,在接收到GATT_CONNECT_CFM消息后,调用gattManagerClientRemoteServerConnected ()接口用于确认连接,完成连接的三次握手过程。
2. GATT支持notification和indication操作,因此客户端需要有着两种请求操作对应的接口。gattManagerClientRemoteServerNotification()和gattManagerClientRemoteServerIndication()就是为了实现这两种操作巍峨设计的。
3. 获取服务器的服务。根据GATT标准,获取服务的服务主要有:获取服务器主要GATT服务,获取某个GATT服务的所有特征值定义,获取某个GATT服务的特征值描述符,读/写某个特征值等。
&&&&&&&& 作为BLE服务器主要完成的任务有:
1.广播,以及处理客户端的连接请求。gattManagerServerAdvertising()开启广播,GattManagerWaitForRemoteClient()等待远程客户发起连接,gattManagerServerConnectInd()处理连接请求。gattManagerServerRemoteClientConnected()处理连接请求确认(三次握手最后一次)消息。
2.注册GATT service。GattManagerRegisterServer()向GATT MGR模块注册一个GATT service。
3.处理来自客户端的GATT操作,如access,indication,notification等。其中indication,notification操作都是由服务器主动对客户端发起的操作,因此客户端和服务器端处理的消息刚好是互为匹配的,即服务器处理的消息有(GATT_ACCESS_IND, GATT_NOTIFICATION_CFM, GATT_INDICATION_CFM),客户端对应的处理消息有(ATT_ACCESS_RSP, GATT_NOTIFICATION_IND, GATT_INDICATION_IND)。
1.1.2&&& GATT数据库
作为GATT的服务器,通常需要存储比较多的数据来支撑多个不同的GATT服务,因此在GATT服务器端,建立一个数据库是必要的。在CSR的BlueCore和CSRμEnergy软件开发工具包(SDK)中使用了一种特殊的数据库目标语言。该数据库通过GATT数据库生成器(CSR提供的gattdbgen.exe)自动生成。这就允许应用程序开发者以一种简单易读,便于维护的方式来创建一个数据库,避免采用诸如SDP这种用复杂的二进制形式表示方式。
数据库的生成
GATT数据库生成器输入一个用jeason语言描述的GATT服务文件foobar.db,输出一个foobar.c和foobar.h文件,这两个文件可以作为ADK工程的一部分进行编译和链接。可见数据库的生产是在整个工程编译前,准确的说是在预编译阶段就已经完成了。显然这样生产的数据是一个准常量的数据库,不能往里面新增记录,即不能动态的添加GATT服务,所有的服务必须在编译前就已经确定好。
例如,在ADK的sink例程中,sink_gatt_db.db作为数据库生成器的输入文件,输出sink_gatt_db.c和sink_gatt_db.h。
其中xxx_db.c文件有const uint16 gattDatabase[] = {}存储数据库记录。并提供两个接口工外部操作数据库,这两个接口分别为:
uint16 *GattGetDatabase(uint16 *len); &/*获取数据库存储区首地址*/
uint16 GattGetDatabaseSize(void);&&&&& /*获取数据库大小*/
在xxx_db.h文件中,除了GattGetDatabase()和GattGetDatabaseSize()接口的声明外,还有数据库中所有ATT记录的句柄(UUID)的宏定义,通常以HANDLE_GAIA_XXX的形式定义。通过该宏,可以快速索引某条ATT记录。
BLE在初始化GATT Manager模块时,对GATT database进行了初始化:
initialiseGattWithServers()-&
GattManagerRegisterConstDB(&gattDatabase[0], GattGetDatabaseSize());
例如某个gaia_db.db内容为:
primary_service {
&&& uuid : 0x01,&
&&& name : "GAIA_SERVICE",
&&& characteristic {
&&&&&&& uuid&&&&&&& : 0x02,
&&&&&&& name&&&&&&& : "GAIA_COMMAND_ENDPOINT",
&&&&&&& flags&&&&&& : [ FLAG_IRQ, FLAG_DYNLEN, FLAG_ENCR_W ],
&&&&&&& properties& : [ write ],
&&&&&&& value&&&&&& : 0x0
则其生成的gaia_db.c文件如下:
/* Static GATT database */
const uint16 gattDatabase[] = {
&&& /* 0001: Primary Service 0001 */
&&& /* 0002: Characteristic Declaration 0002 */
&&& 0x3, 0x0,
&&& /* 0003: . */
&&& 0xdd01, 0x0000,
uint16 *GattGetDatabase(uint16 *len)
&&& uint16 *rc = PanicUnlessMalloc(sizeof(gattDatabase));
&&& *len = sizeof(gattDatabase);
&&& memmove(rc, gattDatabase, sizeof(gattDatabase));
uint16 GattGetDatabaseSize(void)
&&& return sizeof(gattDatabase);
其生成的gaia_db.h文件如下:
#define HANDLE_GAIA_SERVICE&&&&&&&&&&& &(0x0001)
#define HANDLE_GAIA_SERVICE_END&&&&&&&& (0xffff)
#define HANDLE_GAIA_COMMAND_ENDPOINT&&& (0x0003)
uint16 *GattGetDatabase(uint16 *len);
uint16 GattGetDatabaseSize(void);
数据库维护
&&&&&&&& GATT数据库的数据单元是ATT记录,通过某条ATT记录的句柄(handler)可以快速和唯一地访问该条记录,例如,如果希望访问电池服务的电量特征值,该条特征值定义封装在一条句柄为0x0003的ATT记录中,通过句柄0x0003找到该条ATT记录,ATT.value即对应着电池电量值。Java学习(2)
基于UDP模式的C/S通信
这是Client端的:
import java.net.*;
import java.io.*;
public class UDPClient{
public static void main(String args[]){
DatagramSocket socket =
DatagramPacket packet =
InetAddress address =
String s = &send the data , please !&;
byte buf[] = new byte[256];
buf = s.getBytes();
byte ip[] = {(byte)127,(byte)0,(byte)0,(byte)1};
address = InetAddress.getByAddress(ip);
socket = new DatagramSocket();
packet = new DatagramPacket(buf,buf.length,address,1080);
socket.send(packet);
Thread.sleep(2000);
packet = new DatagramPacket(buf,buf.length);
socket.receive(packet);
s = new String(packet.getData());
System.out.println(&received data is :&+s);
}catch(Exception e){
System.out.println(e.toString());
socket.close();
这是Sever端的:
import java.net.*;
import java.io.*;
import java.util.*;
public class UDPSever{
public static void main(String args[]){
DatagramSocket socket1=
DatagramPacket packet1=
String s1;
byte buf1[]= new byte[256];
InetAddress address1 =
int port1;
Date date1;
socket1 = new DatagramSocket(1080);
packet1 = new DatagramPacket(buf1,buf1.length);
socket1.receive(packet1);
s1=new String(packet1.getData());
System.out.println(&received request:&+s1);
port1 = packet1.getPort();
address1= packet1.getAddress();
date1 = new Date();
s1 = date1.toString();
buf1= s1.getBytes();
packet1= new DatagramPacket(buf1,buf1.length,address1,port1);
socket1.send(packet1);
Thread.sleep(2000);
}catch(Exception e){
System.out.println(e.toString());
socket1.close();
如果把这IP地址改改。就可以做简单的网络通信。
网络编程刚接触,慢慢学习。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15924次
排名:千里之外
原创:44篇
(1)(2)(11)(4)(2)(2)(4)(1)(1)(1)(1)(1)(4)(6)(5)(2)(2)(1)1.BLEclient和server;通俗地说吧,Server(服务器)就是数据中心,;Server首先将一个服务按“属性/句柄/数值/;句柄(Handle)就是服务数据在数据中心的地址;大致分三类:读取服务的值,需要知道服务的UUID;根据服务的UUID调用API函数GATT_Rea;蓝牙通信中,Server不能直接访问(读/写)C;2.RSSI的机制和获
client和server
通俗地说吧,Server(服务器)就是数据中心,Client(客户端)就是访问数据者。特别说明,它与主/从设备是独立的概念:一个主设备既可以充当Server,又可以充当Client;从设备亦然
Server首先将一个服务按“属性/句柄/数值/描述”这种格式予以组织,然后调用API函数GATTServApp_RegisterService将服务数据进行注册。举个实例吧,设提供一个电池电量服务字节,它允许Client读取,数据为一个8比特无符号数(0~100%),它的组织如下:02 25 00 19 2A, 这5个数据(小端格式)分别是:0x02=只读属性,0x0025=句柄;0x2A19=服务UUID。
句柄(Handle)就是服务数据在数据中心的地址,当所有的服务数据组织起来后,它总得有个先后顺序,某个服务的位置就是它的句柄。还是上面的类比,如果想去图书馆借阅《现代操作系统》,需要查明该书在哪一层楼,哪个房间,这就是该书的Hanle
大致分三类:读取服务的值,需要知道服务的UUID或者Handle;写服务的值,需要知道服务的Hanle;写服务描述符,需要知道该Descriptor的Hanle。
根据服务的UUID调用API函数GATT_ReadUsingCharUUID 协议栈会返回该服务的Handle。特别注意的是,一个服务的Descriptor的Handle总是该服务的Handle+1,如电池电量服务的Handle是0x0025,那么它的Descriptor的Handle是0x0026
蓝牙通信中,Server不能直接访问(读/写)Client,但是可以通知(Notification)Client,通知的前提是Client通过写Descriptor使能通知功能。例如,某Server发现电池电量已经低于安全阀值,它可以调用GATT_Notification通知所有已连接的Client,但是Client接收后如果处理是它自己的事情。
2. RSSI的机制和获取方法
问:如何知道两个蓝牙通信节点之间的距离?
答:要知道蓝牙通信节点(如手机和蓝牙设备)之间的距离,最容易实现的方法是通过读取接收RSSI(Received Signal Strength
Indication)值来计算。无线通讯中功率与距离的关系如下:
其中A可以看作是信号传输1米远时接收信号的功率, n是传播因子(它受障碍,温度和湿度等影响),r是节点之间的距离。当确定了常数A与n的值后,距离r就可以根据PR(dBm)计算出来。
问:如何获取蓝牙节点的接收RSSI值?
答:具体的设备接收RSSI值的方法不一样,以iPhone手机为例,iOS提供API函数获取RSSI值;TI公司的CC2540芯片的BLE协议栈中,首先将读取RSSI值回调函数挂载到gapRolesRssiRead_t类型的指针下,建立连接后,主设备调用GAPCentralRole_StartRssi(),从设备调用
GAPRole_SetParameter(GAPROLE_RSSI_READ_RATE, ??)。这样就可以定时读取接收的RSSI值了。
得到指数函数公式为:y = -49.53 C 17.7 ln (x),再把自然对数换成10常用对数,则有:y = -49.53 C 40.71 lg (x)。通过以上几步就轻松得到RSSI与距离之间的计算公式
3. 特征值如何获取,各profile在架构中的作用
1、profile
profile可以理解为一种规范,一个标准的通信协议,它存在于从机中。蓝牙组织规定了一些标准的profile,例如 HID OVER GATT ,防丢器,心率计等。每个profile中会包含多个service,每个service代表从机的一种能力。
2、service
service可以理解为一个服务,在ble从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个characteristic特征值。每个具体的characteristic特征值才是ble通信的主题。比如当前的电量是80%,所以会通过电量的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取80%这个数据
3、characteristic
characteristic特征值,ble主从机的通信均是通过characteristic来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容。
UUID,统一识别码,我们刚才提到的service和characteristic,都需要一个唯一的uuid来标识
整理一下,每个从机都会有一个叫做profile的东西存在,不管是上面的自定义的simpleprofile,还是标准的防丢器profile,他们都是由一些列service组成,然后每个service又包含了多个characteristic,主机和从机之间的通信,均是通过characteristic来实现。
3.3.1通用访问配置文件(GAP)
BLE协议栈中的GAP层负责处理设备访问模式和程序,包括设备发现、建立连接、终止连接、初始化安全特色和设备配置.
GAP层总是作为下面四种角色之一:
广播者--不可连接的广告设备
观测者--扫描设备,但不发起建立连接
外部设备--可连接的广告设备,可以在单个链路层连接中作为从机.
集中器--扫描广告设备并发起连接,在单链路层或多链路层作为主机.
目前BLE协议栈支持一个集中器连接三个外设.
外部设备广告特定的数据使集中器知道它是一个可以连接的设备。广告内容包括设备地址以及一些额外的数据,如设备名等。集中器收到广告数据后向外部设备发送扫描请求,然后外部设备将特定的数据回应给集中器,称为扫描回应。集中器收到扫描回应后便知道这是一个可以建立连接的外部设备。这就是设备发现的全过程。此时集中器可以向外部设备发起建立连接的请求。连接请求包括下面一些链接参数:
连接间隔--在两个BLE设备的连接中使用跳频机制,两个设备使用特定的信道收发数据,然后过一段时间后再使用新的信道(链路层处理信道切换),两个设备在信道切换后收发数据称之为连接事件。即使没有应用数据的收发,两设备仍然会通过交换链路层数据来维持连接,连接间隔就是两个连接事件之间的时间间隔,连接间隔以1.25为单位,连接间隔的值为6(7.5ms)~3200(4s).不同的应用可能要求不同的时间间隔。长的时间间隔的优势是显著地节省功耗,因为设备可以在连接事件之间有较长时间的休眠,坏处是当设备有应用数据需要发送时,必须要等到下一个连接事件;短的时间间隔优势是两设备连接频发,可以更快地收发数据,不利之处是设备因连接事件的到来而被频繁的唤醒,会有较多功耗.
从机延迟--这个参数的设置可以使从机(外部设备)跳过若干连接事件,这样外设就更加灵活,在没有数据发送时,可以选择跳过连接事件继续休眠以节省功耗.
管理超时--这是两个成功连接事件之间的最大允许间隔,如果超过了这个时间而没有成功地连接事件,设备被认为是丢失连接,返回到未连接状态.这个值的单位是10ms,
管理超时的范围是10(100ms)~3200(32s),另外、超时值必须大于有效的链接间隔(有效的链接间隔=连接间隔*(1+从机延迟)).
外设可以通过向集中器发送”连接参数更新请求”来改变连接设置,这个请求由协议栈的L2CAP层处理,这个请求包含4个参数:最小连接间隔、最大连接间隔、从机延迟、超时。集中器收到请求后,可以选择接受或拒绝这些新的参数.连接可以被主机或从机以任何原因自动终止,一方发其终止连接时,另一方必然响应,然后两个设备才能退出连接状态.
GAP层也处理BLE连接中安全特征的初始化。只有在已认证的连接中特定的数据才能被读写,一旦连接建立,两个设备进行配对,当配对完成后,形成加密链接的密钥.典型应用中外设请求集中器提供密钥来完成配对工作,密钥可以是一个固定的值,如000000,也可以随机生成一个数据提供给使用者,集中器设备发送正确的密钥后,两设备交换安全密钥并加密认证链接。
在许多情况下,同一对外设和集中器会不定时地连接和断开,BLE的安全机制中有一项特性允许两个设备之间建立长期的安全密钥信息,这种特性称为绑定,它允许两设备重新连接时快速地完成加密认证,而不需要每次连接时执行配对的完整过程.
3.3.2 通用属性配置文件(GATT)
两个设备应用数据的通信是通过协议栈的GATT层实现,从GATT角度来看,当两个设备建立连接后,它们处于下面两种角色之一:
GATT服务器--为GATT客户端提供数据的服务的设备
GATT客户端--从GATT服务器读写应用数据的设备.
GATT角色中的客户端和服务器的概念与链路层的主机和从机概念完全独立,与GAO角色中的外设和集中器概念也是完全独立.
一个GATT服务器中可包含一个或多个GATT服务,GATT服务是完成特定功能的一系列数据的集合。
“特性”(Characteristic)是服务用到的值,以及其内容和配置信息.GATT定义了在BLE连接中发现、读取和写入属性的子过程。GATT服务器上的特性值,及其内容和配置信息(称为描述符)存储于属性表中。属性表是一个数据库,包含了成为属性的小块数据,除了值本身,每个属性都包含下列属性:
句柄--属性在表中的地址,每个属性有唯一的句柄
类型--表示数据代表的事务,通常是蓝牙技术联盟规定或用户自定义的UUID(Universally Unique Identifier)
权限--规定了GATT客户端设备对属性的访问权限,包括是否能访问和怎样访问.
GATT定义了若干在GATT服务器和客户端之间的通信的子过程.
读特性值--客户端设备请求读取句柄处的特性值,服务器将此值回应给客户端.
使用特性的UUID读--客户端请求读基于一个特定类型的所有特性值,服务器将所有与指定类型匹配的特性的句柄和值回应给客户端设备。
读多个特性值--客户端一次请求中读取几个句柄的特性值,服务器将这些特性值回应给客户端,客户端需要知道如何解析这些不同的特性值数据
读特性描述符--客户端请求读特定句柄处的特性描述符,服务器将特性描述符的值回应给客户端设备。
使用UUID发现特性--客户端通过发送”特性”的类型(UUID)来请求发现这个”特性”的句柄。服务器将这个”特性”的声明回应给客户端设备,其中包括特性值的句柄以及”特性”的权限.
写特性值--客户端设备请求向服务器特定的句柄处写入特性描述符,服务器将特性描述符是否写入成功的信息反馈给客户端。
特性值通知--服务器将一个特性值通知给客户端,客户端设备不需要向服务器请求这个数据,客户端收到这个数据时,也不需要回应服务器,要想使能服务器通知,首先要配置好特性,profile中定义了什么时候服务器应该发送这个数据。
每个Profile初始化其相应的服务并内在的通过设备的GATT服务器来注册服务。GATT服务器将整个服务加到属性表中,并为每个属性分配唯一句柄.
GATT属性表中有一些特殊的属性类型,其值由蓝牙技术联盟定义. 7. payload包格式
1.总体结构:
preamble(1 Byte)+ Access Address(4 Bytes)+ PDU + CRC(3 Bytes) preamble =
Access Address = 0x8e89bedd6
Header(2 Bytes)+ Payload (37 Bytes max.)
1)0000 - connected undirected advertising event 可连接非定向广播事件
2)0001 - connected directed advertising event 可连接定向广播事件
3)0010 - non-connected undirected advertising event 不可连接非定向广播事件 4)0011 - response to scan request form scanner扫描请求响应
5)0101 - connect request by initiator连接请求
6)0110 -connected directed advertising event 可发现非定向广播事件
? 非定向广播包(Undirected advertising packets)
= AdvA (6 Bytes) + AdvData (31 Bytes max.) ;
contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0;
? 定向广播包(Directed advertising packets)
= AdvA (6 Bytes) + InitA(6 Bytes) ;
contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0;
// InitA contains initiator's address if RxAdd = 1, or a random address if RxAdd = 0;
3. 扫描请求及扫描响应
Header(2 Bytes)+ Payload (37 Bytes max.)
1)0011 - scan request for further information from advertiser 扫描请求
2)0100 - response to scan request from scanner 扫描响应 ? 扫描请求
= ScanA (6 Bytes) + AdvA(6 Bytes) ;
contains Scanner's public address if TxAdd = 1, or a random address if TxAdd = 0;
contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0;
? 扫描响应 Payload
AdvA(6 Bytes) + ScanRspData(0~31Bytes);
// ScanRspData data from advertiser’
contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0;
3. 连接请求
Header(2 Bytes)+ Payload (34 Bytes)
Header:0101 - connect request by initiator
Payload =InitA(6 Bytes)+ AdvA(6bytes)+ LLData(22 Bytes)
LLData 包含连接信息,详细结构参考bluetooth 4.0 协议。
4. LL 数据通道及控制包
Header(2 Bytes)+ Payload (27 Bytes max.)
Header:详细说明参考bluetooth 4.0 协议;
? LL 数据通道
= 0~27 bytes
? LL 控制包
Payload = 1~23 Bytes
若只考虑蓝牙设备连接之后,评估数据传输速率
包含各类专业文献、中学教育、各类资格考试、专业论文、高等教育、生活休闲娱乐、行业资料、幼儿教育、小学教育、14BLE学习笔记2等内容。 
 simpleblebroadcaster.c) BLE 学习应用笔记 2 1.安装 D:\TI 资料\BLE-Stack 安装目录文件夹下 C:\Texas Instruments\BLE-CC254x-1.2.1\Projects\ble 下有...  BLE学习笔记(CC254X)2---连接参数_计算机软件及应用_IT/计算机_专业资料。BLE 学习笔记(CC254X)2---连接参数() 我们知道 BLE 最大的特点是低功...  C++&C学习笔记 143页 2财富值 C++学习笔记---C++基础 16页 5财富值 Effective...(side + 10.0); // ra is tempoary varia ble 参数 side、lens[2]、rd...  TI CC254x学习笔记整理_计算机硬件及网络_IT/计算机_专业资料。TI CC2541蓝牙...主要用于实现的是 2 个代码文件: OSAL_SimpleBLEPeripheral.c 任务回调函数数据...  将 test 表中的 Count 列宽度加长为 10 个字符 sql&alter atble test ...1/2 相关文档推荐 Oracle学习笔记(已总结) 58页 1下载券 ORACLE学习笔记总结...  BLE蓝牙 4.0 学习笔记_计算机软件及应用_IT/计算机_专业资料。蓝牙 4.0 BLE ...蓝牙 4.0 BLE 数据传输 (二) 在第一部分我们了解了几个专业词汇,接下来我们...  初中英语语法学习笔记_英语_初中教育_教育专区。1 (...2 1 (see 、hear 、notice 、find 、feel 、...She is in trouble They are in tronble 46 48 ...  初中英语语法学习笔记整理_专业资料。初中英语语法学习...2 (比较级 + and + 比较级) 表示越来越怎么样 ...She is in trouble They are in tronble 46 be ...  She is in trouble They are in tronble 46 47 be late for = come late...1/2 相关文档推荐 初中英语语法学习笔记 16页 免费 初中英语语法 25页 免费 ...}

我要回帖

更多关于 tcp sever client 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信