如何修改文件描述符ble profiles描述符

今天看啥 热点:
BLE-NRF51822教程5-静态密码设置nordicBLE交流群这一讲介绍配对的一些相关理论知识,并且介绍如何实现”静态密码”的设定 程序是基于sdk9.0 下的 uart demo 另外 测试使用的手机app是 IOS下的lightblue。 这里准确的说法应该是叫配对码,而不是密码。输入这个这个配对码是配对过程中可选的一部分 介绍如何设置静态密码前先介绍一下配对的相关知识(后面都直接叫密码,而不是配对码) 起初未提供安全性的两个设备如果希望做一些需要安全性的工作,就必须先配对。配对涉及两个设备的身份认证,链路加密。如果配对时设置了绑定位,随后还会有一个秘钥分配。分配的秘钥用户可以存储在flash中这样两个设备再第二次重连时的安全启动会更快。而不需要像第一次一样需要再启动整个配对过程。 配对的第一个过程首先是配对信息的交换,这些信息用于确定认证方式,以及后续是否需要分配密钥以及分配哪些密钥。 交换的信息包括: 两端设备的输入输出能力如:是否有显示屏,键盘等。 是否需要绑定(如果设置了绑定位配对的)。 是否需要MITM,是否使用OOB等 这些信息会让BLE协议栈确定一种认证方式: 比如:
1:如果两端设备的输入输出能力有限,比如都没有键盘和显示器,认证方式就是just work,这其实就是没有认证,
2:如果两端设备一个有显示频,而另一个有键盘,而配对中设置了MITM保护。那么认证方式就是passkey entery。一端会显示一个配对码,另一需要输入这个配对码。之后的配对才能正确进行下去。
3:如果设置了OOB,那么这个配对码就是通过另外的通信方式(如NFC)来发送的,而不是像上面一样一端显示一端输入。 这一讲的密码设置就是第二种情况。显示的密码是可以随机的也可以是静态的。由于设备并没有显示器。但是我们仍然可以设置输入输出能力为有显示器,因为我们使用的是静态密码。
配对的过程不仅只是输入配对码这样,后续还会根据输入的配对码,以及两端设备交换的随机数来生成链路密钥来加密链路以及分配后续的长期密钥,身份解析密钥等需要的密钥 配对相关的理论比较多,上面的描述只是一个大概的过程。配对过程的详细介绍在蓝牙规范的 安全章节中。 根据上面的理论描述,我们来总结一下:
我们需要的输入“密码”这个功能,其实是配对过程中的一部分。而配对过程又是需要首先交换配对信息,然后协议栈会根据交换的信息才决定是否有输入密码这一过程。 那么我们要做的有如下几步:
1: 首先设置要输入的静态密码2: 设置配对时会交换的信息:根据上面的介绍如果我们需要手机输入密码,那么配对时就要设置只具有显示器(这样就会是一端显示,一端输入,虽然我们真的没显示器,但是设置的是静态密码所以也是可以的),设置需要MITM攻击保护。
3:触发配对。 下面先介绍如何设置静态密码: //首先定义一下静态密码,配对密码只能是 6-digit ASCII string #defineSTATIC_PASSKEY "123456"
/**< Static pin. *///改结构体中可以设置静态密码
staticble_opt_t
m_static_pin_定义了这两个参数后,我们需要设置一下静态密码,设置的操作需要在协议栈初始化之后 所以我们将设置密码操作放在 gap_params_init()函数的最后 如下: static void gap_params_init(void){ //前面都是设置一些设备名以及一些后续需要协商的连接参数
//详细解释在 串口透传剖析 中有说明 uint32_t err_ble_gap_conn_params_tgap_conn_ble_gap_conn_sec_mode_t sec_BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);err_code=sd_ble_gap_device_name_set(&sec_mode,(constuint8_t*DEVICE_NAME,trlen(DEVICE_NAME));APP_ERROR_CHECK(err_code);memset(&gap_conn_params, 0,sizeof(gap_conn_params));gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;gap_conn_params.slave_latency= SLAVE_LATENCY;gap_conn_params.conn_sup_timeout= CONN_SUP_TIMEOUT;err_code = sd_ble_gap_ppcp_set(&gap_conn_params);APP_ERROR_CHECK(err_code); //以下是设置静态密码操作
uint8_tpasskey[] = STATIC_PASSKEY;
m_static_pin_option.gap_opt.passkey.p_passkey=//该系统调用执行密码的设置操作。
err_code=sd_ble_opt_set(BLE_GAP_OPT_PASSKEY,&m_static_pin_option) APP_ERROR_CHECK(err_code);
}到这里设置静态密码的操作就做完了。 然后是设置配对时要交换的信息: 下面定义我们需要交换的信息的宏,也就是和安全参数相关的一些宏。 //这里只是演示静态密码,不需要绑定 #define SEC_PARAM_BOND 0//因为要输入密码,就是一种MITM攻击保护,所以这里设置MITM #define SEC_PARAM_MITM 1//这里设置只有显示屏(其实没有,但是我们用的是事先知道的静态密码所以不// 需要显示) #define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_DISPLAY_ONLY//不使用带外数据 #define SEC_PARAM_OOB 0//链路加密密钥的长度 #define SEC_PARAM_MIN_KEY_SIZE 7#define SEC_PARAM_MAX_KEY_SIZE 16定义了宏之后我们需要在设置参数,写一个如下的函数。 m_sec_params 是一个全局变量 ble_gap_sec_params_t m_sec_static void sec_params_init(void){ m_sec_params.bond = SEC_PARAM_BOND;m_sec_params.mitm =SEC_PARAM_MITM;m_sec_params.io_caps =SEC_PARAM_IO_CAPABILITIES;m_sec_params.oob =SEC_PARAM_OOB;m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE;m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE;}将该函数放在 main函数的初始化流程中的conn_params_init(); 函数之后。 设置的这个全局变量会在配对启动后的信息交换中使用(因为其内部值就是要交换的信息)。 到这里我们设置完了配对启动后会交换的信息。但是怎么把这个信息给对端设备呢? 先看完最后一步的触发配对的问题,再来解决将配对信息发给对端设备的问题。 最后一步触发配对: 配对的触发有以下几种情况:
1:主机直接发起。
2:从机发起安全请求,如果之前绑定过,那么主机会直接用用保存的LTK加密链路,如果没有那么主机会发起配对请求。 3:BLE中的有一个安全模式的概念。当某个属性被设置为需要认证的加密链路访问时,那么当在主机访问从机的属**器时,如果链路是不安全的就会返回错误,然后主机会发起配对请求从而实现安全要求。 我们采用的就是第三种 被动等待主机触发的方式,那么首先要做的就是将一些属性设置为需要安全的链路才能访问,那么手机在访问时就会触发配对过程了。 因为我们是基于 9.0SDK 下的uartdemo,所以我们将具有notify 性质RX 特征值的 cccd(客户端配置描述符)设置为需要认证和加密的安全链路。 因为手机端使能notify是需要写CCCD的 那么当手连上板子后 点击rx特征值的notify 按钮后主机会发一个 写命令写板子上的rx特征值的cccd,因为初试链路是不完全的,那么这时手机就会返回写出错,然后启动配对过程。 设置如下: 在添加RX特征值的函数中做如下的简单就可以了。
这里只截取部分代码: static uint32_t rx_char_add(ble_nus_t * p_nus, constble_nus_init_t * p_nus_init){ /**@snippet [Addingproprietary characteristic to S110 SoftDevice] */ ble_gatts_char_md_tchar_ ble_gatts_attr_md_tcccd_ ble_gatts_attr_t attr_char_ ble_uuid_t ble_ ble_gatts_attr_md_tattr_memset(&cccd_md, 0, sizeof(cccd_md));BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);//BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);//将上面的一行修改成下面这行 BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&cccd_md.write_perm);
cccd_md.vloc =BLE_GATTS_VLOC_STACK;memset(&char_md, 0, sizeof(char_md));·············· ·············· ············ }这样当对端设备(如手机)使能开发板的上rx特征值的notify功能时,就会
因为没有写权限而触发配对,手机会发来配对请求,然后板子回复配对信息, 怎么回复? 这就是第二步中最后留下的问题。如何将配对信息交给对端设 备(手机)。 当手机发来配对请求时,这对板子来说是一个事件,即配对事件。最终由 dispatch派发函数交给各个服务或模块的事件处理函数。 那么我们要做的就是在收到这个配对请求事件后回复第二步中设置的配对 信息就可以了。在main.c 文件中的的on_ble_evt做如下修改 staticvoidon_ble_evt(ble_evt_t * p_ble_evt){ uint32_terr_switch(p_ble_evt->header.evt_id) {caseBLE_GAP_EVT_CONNECTED:err_code= bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code);m_conn_handle= p_ble_evt->evt.gap_evt.conn_caseBLE_GAP_EVT_DISCONNECTED:err_code= bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code);m_conn_handle= BLE_CONN_HANDLE_INVALID;caseBLE_GAP_EVT_SEC_PARAMS_REQUEST: //注释掉原本的不支持配对的函数,改为如下的配对回复函数 //err_code= sd_ble_gap_sec_params_reply(m_conn_handle, //BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
err_code=sd_ble_gap_sec_params_reply(m_conn_handle,
BLE_GAP_SEC_STATUS_SUCCESS,&m_sec_params,NULL);
APP_ERROR_CHECK(err_code);caseBLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have beenstored.err_code=sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code);default: // No implementation needed. }}到这里所有需要配置的都设置完了。程序运行后。手机连接上板子,然后访问rx特征值。因为该特征值是用来将板子数据通过Notify方式传给手机的,那么首先要点击手机上的notify按钮去使能板子的notify功能。当我们点击该按钮时就会弹出输入密码的配对框。
相关搜索:
相关阅读:
相关频道:
Android教程最近更新温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
可以看到80& 06& 00& 01& 00& 00& 12& 00主机发给设备的请求:
bmRequestType=80H说明这是主机发给设备的标准请求;
bRequest=06H说明这句的作用是Get Descriptor
wValue=0100H(注意这是小端模式,高字节在图片里显示在后)说明需要设备上传设备描述符(01)
wLength=0012H(注意这是小端模式,高字节在图片里显示在后)说明设备必须上传12H个字节长度的数据
于是设备上传了0012H长的设备描述符:12& 01& 00& 02& 00& 00& 00& 08& 23& 12& 07& 3f& 10& 11& 01& 02& 00& 01
第四行80& 06& 00& 02& 00& 00& 09& 00主机发给设备请求:
按上面的解释,说明这是主机要求设备上传配置描述符(02H),因为主机无法得知配置描述符里的wTotallength多大,所以先发个标准长度0009H来试探。
于是设备上传了09H长的配置描述符:09& 02& 3b& 00& 02& 01& 00& a0& 32
主机得知配置总的含有003bH个字节,于是再次发给设备上传配置描述符的请求:80& 06 00 02 00 00 3b& 00,要求的总字节长度为003bH
之后设备上传了003bH的数据:9个配置描述符+9个接口0描述符+9个HID描述符+7个端点1描述符+9个接口1描述符+9个HID描述符+7个端点1描述符
之后主机进行设置配置:00& 09& 01& 00& 00& 00& 00& 00 设置了配置描述符,使能端点1和端点2
因为有2个接口,所以分2次分别设置:
EP1:读取设备描述符,试探性配置描述符,返回键盘的配置描述符长度0022H,再次以0022H长度读取配置描述符。设置配置描述符,挂起等配置完成。
配置完成后读取HID报告:81& 06& 00& 22& 00& 00& b5& 00
81代表主机发给设备的接口&& 06代表Get Descriptor&& 22H为HID报告& wIndex:00为接口0& 长度为75H+40H=b5H(?)
设备上传接口0的0075H长度字节HID报告。
开始设置接口1,仍然继续读取设备描述符试探性配置描述符,返回键盘的配置描述符长度0022H,再次以0022H长度读取配置描述符。设置配置描述符,挂起等配置完成。
配置完成后读取HID报告:不同的是wIndex:0001H 配置接口1,长度为34H+40H=74H(?)
设备上传接口1的0034H长度字节HID报告。结束后SET REPORT,结束,等待设备上传端点键盘鼠标数据。
剩下的是字符串这个不是必须的还没讲到。
阅读(5004)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'USB学习之描述符篇--枚举',
blogAbstract:'
开发无线键鼠有2年多了,一直对HID这东西一知半解。赶在新项目需要重新编写USB描述符部分,开始搜集资料,深入学习。
&&& 枚举可以理解为主机按不定的顺序向USB设备讨要设备信息,好给它分配资源,若枚举不成功,就放弃分配资源,免得浪费资源。一般都是使用中断传输方式通信。
&&& 常用的描述符有以下几种:01H、设备描述符& 02H、配置描述符& 03H、字符串描述符& 04H、接口描述符& 05H、端点描述符
21H:HID描述符 22H:HID报告',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:8,
publishTime:8,
permalink:'blog/static/',
commentCount:1,
mainCommentCount:1,
recommendCount:2,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 如何修改文件描述 的文章

 

随机推荐