低功耗蓝牙BLE之连接事件、连接参数和更新方法
轉(zhuǎn)自:http://blog.csdn.net/zzfenglin/article/details/51304084
連接事件
在一個連接當中,主設(shè)備會在每個連接事件里向從設(shè)備發(fā)送數(shù)據(jù)包。一個連接事件是指主設(shè)備和從設(shè)備之間相互發(fā)送數(shù)據(jù)包的過程。連接事件的進行始終位于一個頻率,每個數(shù)據(jù)包會在上個數(shù)據(jù)包發(fā)完之后等待150μs再發(fā)送。
連接間隔決定了主設(shè)備與從設(shè)備的交互間隔;它是指兩個連續(xù)的連接事件開始處的時間距離,可以是7.5ms ~ 4s內(nèi)的任意值,但必須為1.25ms的整數(shù)倍。要確定從設(shè)備與主設(shè)備的實際交互間隔,需要用到從設(shè)備延遲這一參數(shù),代表從設(shè)備在必須偵聽之前可以忽略多少個連接事件。
如下圖所示,連接事件被一個個的連接間隔分開。從主設(shè)備發(fā)送數(shù)據(jù)包開始,每個連接事件可以持續(xù)進行,直至主設(shè)備或從設(shè)備停止響應(yīng)。在連接事件之外,主從設(shè)備之間不發(fā)送任何數(shù)據(jù)包。
舉個例子,如果連接間隔為100ms,從設(shè)備延遲是9,那么從設(shè)備可以忽略9個鏈接事件,但不得不偵聽第10個連接事件。換言之,從設(shè)備必須每秒偵聽一次,而此時監(jiān)控超時的最小值應(yīng)為1010ms。反過來,另一個極端的例子是,如果監(jiān)控超時使用了32s的最大值,對于間隔為100ms的鏈路,從設(shè)備延時必須小于等于319。
雖然如此,如果將從設(shè)備延遲設(shè)為可行的最大值,在監(jiān)控超時發(fā)生前從設(shè)備只能獲得唯一一次偵聽主設(shè)備的機會,這可不是一個好主意。因此,建議至少給從設(shè)備留出6次偵聽的機會。在前面的例子中,如果連接間隔為100ms,從設(shè)備延遲為9,那么監(jiān)控超時應(yīng)該至少為6s,這樣一來,鏈路在最終斷開前從設(shè)備至少會有6次偵聽的機會。
連接參數(shù)介紹
主設(shè)備和從設(shè)備建立連接之后,所有的數(shù)據(jù)通信都是在連接事件(ConnectionEvents)中進行的。
尖刺的波就是連接事件(Connectionevents),剩下的Sleeping是睡眠時間,設(shè)備在建立連接之后的大多數(shù)時間都是處于Sleeping,這種情況下耗電量比較低,而在連接事件(Connectionevents)中,耗電量就相對高很多,這也是BLE為什么省電的原因之一。
每個連接事件(Connectionevents)中,都需要由Master發(fā)起包,再由Slave回復(fù)。
Master即主機,簡稱M;Slave即從機,簡稱S。抓包過程中看到的M->S或者S->M即主機到從機或者從機到主機。
連接參數(shù) (ConnectionParameters):
通過修改下面三個參數(shù),就可以設(shè)置BLE連接過程中的傳輸速度和功耗。
1.ConnectionInterval(連接間隔)
ConnectionInterval(GAPROLE_MIN_CONN_INTERVAL&&GAPROLE_MAX_CONN_INTERVAL)連接間隔,在BLE的兩個設(shè)備的連接中使用跳頻機制。兩個設(shè)備使用特定的信道發(fā)送和接收數(shù)據(jù),然后過一段時間后再使用新的信道(BLE協(xié)議棧的鏈路層處理信道的切換)。兩個設(shè)備在切換信道后發(fā)送和接收數(shù)據(jù)稱為一個連接事件。盡管沒有應(yīng)用數(shù)據(jù)被發(fā)送和接收,兩個設(shè)備仍舊會交換鏈路層數(shù)據(jù)(空包 EmptyPDU)來維持連接。
這個連接間隔就是指在一個連接事件(Connectionevents)的開始到下一個連接事件(Connectionevents)的開始的時間間隔。連接間隔以1.25ms為單元,連接間隔的范圍是6~3200既7.5ms~4s之間。
2.SlaveLatency(從設(shè)備延遲或者從設(shè)備時延)
允許Slave(從設(shè)備)在沒有數(shù)據(jù)要發(fā)的情況下,跳過一定數(shù)目的連接事件(Connectionevents),在這些連接事件(Connectionevents)中不必回復(fù)Master(主設(shè)備)的包,這樣就能更加省電。
范圍可以是0 ~ 499
更詳細的使用解析如下:
SlaveLatency=OFF也就是SlaveLatency為0時,Master發(fā)包,Slave必須回復(fù),如果不回復(fù),Master就會認為Slave那邊接收不正常。
SlaveLatency=ON也就是SlaveLatency不為0的時候,圖中SlaveLatency為3。Master發(fā)包,Slave沒有數(shù)據(jù)要回復(fù)的時候,就會忽略3個連接事件,在第4個連接事件接收到Master發(fā)送的數(shù)據(jù)之后,回復(fù)Master。如果Slave有數(shù)據(jù)要發(fā)送就會喚醒,也就是說即使SlaveLatency為3,但是在Master發(fā)第二包的時候Slave有數(shù)據(jù)要回復(fù),這個時候就會立即回復(fù)Master而不是等到3個連接事件之后的第4個連接事件去回復(fù)。
3.SupervisionTimeout(超時時間或者監(jiān)控超時)
這個參數(shù)設(shè)定了一個超時時間,如果BLE在這個時間內(nèi)沒有發(fā)生通信的話,就會自動斷開。
單位是10ms,該變量的范圍是10 ~ 3200,折算成時間范圍是100ms ~ 32s。
連接間隔、從機時延以及超時時間這三者必須滿足如下公式:
SupervisionTimeout >(1+slaveLatency)*(connectionInterval)
上述公式必須滿足,否則連接就會不正常斷開。
這三個連接參數(shù)不同情況下對通信速率和功耗的影響:
1.ConnectionInterval縮短,Master和Slave通信更加頻繁,提高數(shù)據(jù)吞吐速度,縮短了數(shù)據(jù)發(fā)送的時間,當然也增加了功耗。
2.ConnectionInterval增長,通信頻率降低,數(shù)據(jù)吞吐速度降低,增加了數(shù)據(jù)發(fā)送的時間,當然,這種設(shè)置降低了功耗。
3.SlaveLatency減少或者設(shè)置為0,每次ConnectionEvents中都需要回復(fù)Master的包,功耗會上升,數(shù)據(jù)發(fā)送速度會提高。
4.SlaveLatency加長,功耗下降,數(shù)據(jù)發(fā)送速度降低。
連接參數(shù)更新規(guī)程
連接建立時,主設(shè)備通過鏈接請求數(shù)據(jù)包發(fā)送連接參數(shù)。當連接活躍了一段時間,連接參數(shù)也許不再適用于當前使用的服務(wù)。出于提高效率的目的,連接參數(shù)需要進行更新。較之首先斷開連接、接著更換新參數(shù)重新連接,還有一種在鏈路中更新參數(shù)更為簡單的途徑,如下圖所示:
為此,主設(shè)備向從設(shè)備發(fā)送連接更新請求,即LL_CONNECTION_UPDATE_REQ,當中攜帶了新的參數(shù)。這些參數(shù)不必進行協(xié)商,從設(shè)備或者接受和使用它們,或者斷開鏈路。連接更新請求中包含了早先創(chuàng)建連接時用過的一部分參數(shù),還有一個稱為瞬時(instant)的新參數(shù):
1.傳輸窗口大小
2.傳輸窗口偏移量
3.連接間隔
4.從設(shè)備延遲
5.監(jiān)控超時
6.瞬時
瞬時參數(shù)決定了連接更新的開始時刻。發(fā)送消息時,主設(shè)備為連接更新選定一個未來的時間點,并且放在消息中。接到消息后,從設(shè)備會記住這個未來的時刻,屆時再切換至新的連接參數(shù)。這有助于解決無線系統(tǒng)里的一個最大問題----報文重傳。只要數(shù)據(jù)包的重傳次數(shù)足夠,并最終在瞬時之前傳輸成功,上述過程執(zhí)行起來就不會有問題。但是,如果該數(shù)據(jù)包屆時沒能完成傳輸,鏈路就有可能丟失。
由于低功耗藍牙沒有時鐘,要決定瞬時時刻只有依靠計算連接事件的個數(shù)。因此,每一個連接事件都會被計數(shù),鏈路上的第一個連接事件,也就是在連接請求之后的位于首個傳輸窗口里的連接事件記為0。因此,瞬時實際上是一個連接事件的計數(shù)器,相應(yīng)的連接事件到來時就使用新的參數(shù)。為了讓從設(shè)備收到數(shù)據(jù)包,主設(shè)備必須為其提供足夠的機會。不過從設(shè)備延遲是多少,都應(yīng)該至少保證 6 次數(shù)據(jù)發(fā)送機會。也就是說,如果從設(shè)備延遲為500ms,那么瞬時通常被設(shè)定在3s之后的某個未來時刻。
瞬時到來時,從設(shè)備開始偵聽發(fā)送窗口,就好像連接建立的過程那樣。主設(shè)備能夠調(diào)整從設(shè)備的計時,總體而言不超過1.25ms。不過,由于主設(shè)備可能還是一個經(jīng)典藍牙設(shè)備,上述調(diào)整使其得以協(xié)調(diào)低功耗藍牙從設(shè)備,從而更好地完成調(diào)度。一旦該過程結(jié)束,新的連接間隔、監(jiān)控超時、從設(shè)備延遲值將投入使用。
連接參數(shù)的修改
“連接參數(shù)更新請求”命令可以讓從設(shè)備更新鏈路層的連接參數(shù),如下圖所示。這些參數(shù)包括連接間隔(從設(shè)備希望主設(shè)備允許從設(shè)備發(fā)送數(shù)據(jù)包的頻率)、從設(shè)備延遲(從設(shè)備能夠忽略主設(shè)備的連接事件的最大值)以及監(jiān)控超時。
在連接中,如果從設(shè)備希望修改當前的連接參數(shù)則可以使用該命令。比方說,如果連接事件的間隔有可能太快了,導(dǎo)致過多的電量浪費。這在從設(shè)備時延很大時沒有問題,但如果不是這樣,從設(shè)備將會頻繁的偵聽鏈路。這在一些情況下是必要的,例如設(shè)備間首次綁定、互發(fā)多個數(shù)據(jù)包、探索服務(wù)和設(shè)備特性等。但在很多其他情況下,盡可能地減少從設(shè)備必須偵聽連接事件的數(shù)量對提高電池壽命至關(guān)重要。
連接參數(shù)更新請求命令僅用于從設(shè)備向主設(shè)備發(fā)送,這是由于主設(shè)備隨時都能啟動鏈路層連接參數(shù)更新控制(ConnectionParameterUpdateControl)規(guī)程。如果該命令由主設(shè)備發(fā)送,從設(shè)備會將其視為一個錯誤,并返回帶有“命令不理解”原因代碼的“命令拒絕”命令。
從設(shè)備可以在任何時候發(fā)送該命令;收到該信息的主設(shè)備如果可以修改連接參數(shù),則將返回“連接參數(shù)更新響應(yīng)”(ConnectionParameterUpdateResponse),其中的結(jié)果代碼設(shè)為“接受(accepted)”。隨后,主設(shè)備將會啟動鏈路層連接參數(shù)更新控制規(guī)程。
當然,如果主設(shè)備不同意從設(shè)備的請求參數(shù),它可以發(fā)送結(jié)果代碼為“拒絕(rejected)”的連接參數(shù)更新響應(yīng)命令以拒絕請求。此時從設(shè)備有兩個選擇:要么接受主設(shè)備希望的正在使用的連接參數(shù),要么終止連接。終止連接的做法咋看起來可能讓人覺得很激進,但是,假如使用當前的參數(shù)從設(shè)備將會在一周內(nèi)耗盡電量,而使用請求的參數(shù)則可以持續(xù)數(shù)年,很明顯,合理的選擇只有一個。
修改連接參數(shù)時,如果要減少主設(shè)備拒絕從設(shè)備請求的可能性,可以在請求里設(shè)置一個可接受的參數(shù)范圍。經(jīng)過精心設(shè)計的從設(shè)備會樂意接受很寬的參數(shù)范圍。由于主設(shè)備可能正忙于實時會話音頻連接或者高質(zhì)量語音連接等任務(wù),它可以接受一定范圍內(nèi)的連接間隔參數(shù)。設(shè)備可接受的間隔參數(shù)會根據(jù)當前任務(wù)的不同而不同,可能有別于上一次設(shè)備連接時的參數(shù)。
要提高主設(shè)備接受連接參數(shù)的機率,還有個方法是從設(shè)備提供一個合理的從設(shè)備延遲。主設(shè)備可以選擇最合適的連接事件間隔,從設(shè)備則使用最佳功耗的從設(shè)備延遲參數(shù)。
舉個例子,如果從設(shè)備想每600ms同步一次,它可以請求范圍100ms ~ 750ms的連接間隔參數(shù),并帶上從設(shè)備延遲5。如果主設(shè)備選擇100ms,則從設(shè)備每6個連接事件同步一次;如果主設(shè)備選擇200ms,則從設(shè)備每3個連接事件同步一次,實現(xiàn)其所期望的600ms間隔;如果主設(shè)備選擇300ms,則從設(shè)備忽略每隔一個連接事件同步一次;如果主設(shè)備選擇400ms,則從設(shè)備每400ms同步一次。
下面介紹一下在TI的CC2540和CC2541中,連接參數(shù)修改的方法。
(一)連接成功建立之后從設(shè)備自動申請修改連接參數(shù)。
我們以TI 1.4.0協(xié)議棧中的“simpleBLEPeripheral”工程為例來進行講解,在這個工程的“ProjectsleSimpleBLEPeripheralSourcesimpleBLEPeripheral.c”應(yīng)用文件中定義了如下的宏:
[cpp]view plaincopy
//Whethertoenableautomaticparameterupdaterequestwhenaconnectionisformed
#defineDEFAULT_ENABLE_UPDATE_REQUESTTRUE
從上面的注釋中,我們可以看出這個宏的作用是當一個連接建立的時候,是否需要自動申請連接參數(shù)更新。當設(shè)置為“TRUE”的時候就是需要,當設(shè)置為“FALSE”的時候就是不需要。那這個宏到底是如何起作用的呢?下面我們來看一下。
1.“ProjectsleSimpleBLEPeripheralSourcesimpleBLEPeripheral.c”應(yīng)用文件中的“SimpleBLEPeripheral_Init”初始化方法里對該宏進行了處理,源碼如下:
[cpp]view plaincopy
uint8enable_update_request=DEFAULT_ENABLE_UPDATE_REQUEST;
GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE,sizeof(uint8),&enable_update_request);
2.我們看下“GAPRole_SetParameter”方法里面的相關(guān)的操作,相關(guān)操作在“ProjectsleProfilesRolesperipheral.c”文件里,源碼如下:
[cpp]view plaincopy
caseGAPROLE_PARAM_UPDATE_ENABLE:
if((len==sizeof(uint8))&&(*((uint8*)pValue)<=TRUE))
{
gapRole_ParamUpdateEnable=*((uint8*)pValue);
}
else
{
ret=bleInvalidRange;
}
break;
3.從上面的代碼不難看出,將我們設(shè)置的宏賦給了“gapRole_ParamUpdateEnable”全局變量,下面我們在本文件中搜索一下該全局變量使用的地方,發(fā)現(xiàn)在如下源碼中用到了:
[cpp]view plaincopy
//連接成功建立之后底層返回的事件
caseGAP_LINK_ESTABLISHED_EVENT:
{
gapEstLinkReqEvent_t*pPkt=(gapEstLinkReqEvent_t*)pMsg;
if(pPkt->hdr.status==SUCCESS)
{
VOIDosal_memcpy(gapRole_ConnectedDevAddr,pPkt->devAddr,B_ADDR_LEN);
gapRole_ConnectionHandle=pPkt->connectionHandle;
gapRole_state=GAPROLE_CONNECTED;
if(gapRole_RSSIReadRate)
{
//StarttheRSSIReads
VOIDosal_start_timerEx(gapRole_TaskID,RSSI_READ_EVT,gapRole_RSSIReadRate);
}
//Storeconnectioninformation
//保存連接剛建立時的連接參數(shù)
gapRole_ConnInterval=pPkt->connInterval;
gapRole_ConnSlaveLatency=pPkt->connLatency;
gapRole_ConnTimeout=pPkt->connTimeout;
//Checkwhetherupdateparameterrequestisenabled
//檢測更新連接參數(shù)請求是否被使能
if(gapRole_ParamUpdateEnable==TRUE)
{
//Gettheminimumtimeuponconnectionestablishmentbeforethe
//peripheralcanstartaconnectionupdateprocedure.
//獲取設(shè)置的時間間隔,從機將在連接建立之后
//延時至少該時間間隔之后觸發(fā)連接參數(shù)更新事
//件。
uint16timeout=GAP_GetParamValue(TGAP_CONN_PAUSE_PERIPHERAL);
//在延時timeout*1000ms之后觸發(fā)連接參數(shù)更新事件
osal_start_timerEx(gapRole_TaskID,START_CONN_UPDATE_EVT,timeout*1000);
}
4.上面的注釋非常清楚了,在連接成功建立返回的事件中判斷我們設(shè)置的宏,如果設(shè)置為“TRUE”,那就獲取我們設(shè)置的時間間隔,在延時我們設(shè)置的時間間隔(上面注釋中提到至少,因為用的是系統(tǒng)定時器,有可能在執(zhí)行別的事件,所以實際的延時時間會大于我們設(shè)置的時間,當然,一般情況下偏移的那點時間是可以忽略的)之后,觸發(fā)連接參數(shù)更新事件,進行連接參數(shù)的更新。那上面源碼中獲取的時間間隔以及后面要更新的連接參數(shù)是在什么地方設(shè)置的呢?下面我們繼續(xù)回到應(yīng)用層文件中查看相關(guān)設(shè)置。
5.在“ProjectsleSimpleBLEPeripheralSourcesimpleBLEPeripheral.c”文件中定義了如下宏用來設(shè)置自動更新連接參數(shù)時,相關(guān)連接參數(shù)的值,源碼如下:
[cpp]view plaincopy
//Minimumconnectioninterval(unitsof1.25ms,80=100ms)ifautomaticparameterupdaterequestisenabled
//如果自動更新連接參數(shù)請求被使能的話,用到的最小連接間隔,單位1.25ms
#defineDEFAULT_DESIRED_MIN_CONN_INTERVAL80
//Maximumconnectioninterval(unitsof1.25ms,800=1000ms)ifautomaticparameterupdaterequestisenabled
//如果自動更新連接參數(shù)請求被使能的話,用到的最大連接間隔,單位1.25ms
#defineDEFAULT_DESIRED_MAX_CONN_INTERVAL800
//Slavelatencytouseifautomaticparameterupdaterequestisenabled
//如果自動更新連接參數(shù)請求被使能的話,用到的從機時延
#defineDEFAULT_DESIRED_SLAVE_LATENCY0
//Supervisiontimeoutvalue(unitsof10ms,1000=10s)ifautomaticparameterupdaterequestisenabled
//如果自動更新連接參數(shù)請求被使能的話,用到的超時時間,單位10ms
#defineDEFAULT_DESIRED_CONN_TIMEOUT1000
//ConnectionPausePeripheraltimevalue(inseconds)
//如果自動更新連接參數(shù)請求被使能的話,用到的時間間隔,單位s
#defineDEFAULT_CONN_PAUSE_PERIPHERAL6
6.通過上述宏進行相應(yīng)設(shè)置的地方在“ProjectsleSimpleBLEPeripheralSourcesimpleBLEPeripheral.c”文件的“SimpleBLEPeripheral_Init”初始化方法中,源碼如下:
[cpp]view plaincopy
VOIDGAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL,DEFAULT_CONN_PAUSE_PERIPHERAL);
uint16desired_min_interval=DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16desired_max_interval=DEFAULT_DESIRED_MAX_CONN_INTERVAL;
uint16desired_slave_latency=DEFAULT_DESIRED_SLAVE_LATENCY;
uint16desired_conn_timeout=DEFAULT_DESIRED_CONN_TIMEOUT;
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);
上述操作在“ProjectsleProfilesRolesperipheral.c”文件里的具體實現(xiàn)我們就不一起看了,因為里面其實就是一個賦值的過程,所以大家自行查看即可。
(二)連接成功建立之后從設(shè)備在需要的時候去修改某個連接參數(shù)或者全部的連接參數(shù)。
1.修改單個連接參數(shù)的方法
修改最小連接間隔
[cpp]view plaincopy
uint16desired_min_interval=DEFAULT_DESIRED_MIN_CONN_INTERVAL;
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL,sizeof(uint16),&desired_min_interval);
修改最大連接間隔
[cpp]view plaincopy
uint16desired_max_interval=DEFAULT_DESIRED_MAX_CONN_INTERVAL;
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL,sizeof(uint16),&desired_max_interval);
修改從設(shè)備延遲
[cpp]view plaincopy
uint16desired_slave_latency=DEFAULT_DESIRED_SLAVE_LATENCY;
GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY,sizeof(uint16),&desired_slave_latency);
修改超時時間
[cpp]view plaincopy
uint16desired_conn_timeout=DEFAULT_DESIRED_CONN_TIMEOUT;
GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER,sizeof(uint16),&desired_conn_timeout);
2.所有連接參數(shù)一起修改的方法
[cpp]view plaincopy
uint16minConnInterval;
uint16maxConnInterval;
uint16slaveLatency;
uint16timeoutMultiplier;
//Updateconnectionparameters
GAPRole_SendUpdateParam(minConnInterval,maxConnInterval,slaveLatency,timeoutMultiplier,GAPROLE_TERMINATE_LINK);
GAPRole_SendUpdateParam傳入的前四個參數(shù)在之前都已經(jīng)介紹過了,下面介紹下最后一個參數(shù),最后一個參數(shù)設(shè)置的是連接參數(shù)更新失敗后的操作,可取值定義在peripheral.h文件中,如下:
[cpp]view plaincopy
/**
*Possibleactionstheperipheraldevicemaytakeifanunsuccessfulparameter
*updateisreceived.
*
*ParametersforGAPRole_SendUpdateParam()only
*/
#defineGAPROLE_NO_ACTION0//Takenoactionuponunsuccessfulparameterupdates
#defineGAPROLE_RESEND_PARAM_UPDATE1//Continuetoresendrequestuntilsuccessfulupdate
#defineGAPROLE_TERMINATE_LINK2//Terminatelinkuponunsuccessfulparameterupdates
GAPROLE_NO_ACTION:沒有任何動作
GAPROLE_RESEND_PARAM_UPDATE:重新發(fā)送參數(shù)更新請求
GAPROLE_TERMINATE_LINK:斷開連接
對于上述介紹的兩種修改連接參數(shù)的方法,個人建議還是采用第二種方法,因為第一種方法在修改某一個參數(shù)的時候,可能會導(dǎo)致其他參數(shù)的變化,比如我們只修改了連接間隔,但從機延時可能會隨之改變,這樣我們就無法根據(jù)自己的需求控制連接參數(shù)的更新。
第二種方法在使用的時候有可能碰到一種情況,就是我們只想修改某一個或者某兩個連接參數(shù),剩下的參數(shù)想保持原有的,這樣的話,我們需要在修改連接參數(shù)之前先去讀取連接參數(shù),然后將需要修改的參數(shù)進行重新設(shè)置即可,讀取連接參數(shù)的代碼如下:
[cpp]view plaincopy
uint16interval;
uint16latency;
uint16timeout;
GAPRole_GetParameter(GAPROLE_CONN_INTERVAL,&interval);
GAPRole_GetParameter(GAPROLE_CONN_LATENCY,&latency);
GAPRole_GetParameter(GAPROLE_CONN_TIMEOUT,&timeout);
下面我們通過一個實例來具體了解下連接參數(shù)修改的方法,需求是將連接間隔修改為25,從機延遲修改為8,超時時間不修改,更新失敗后重新發(fā)送參數(shù)更新請求,本實例中主設(shè)備是安卓設(shè)備,從設(shè)備是CC2541。代碼實現(xiàn)如下:
[cpp]view plaincopy
uint16interval;
uint16latency;
uint16timeout;
GAPRole_GetParameter(GAPROLE_CONN_INTERVAL,&interval);
GAPRole_GetParameter(GAPROLE_CONN_LATENCY,&latency);
GAPRole_GetParameter(GAPROLE_CONN_TIMEOUT,&timeout);
GAPRole_SendUpdateParam(25,25,8,timeout,GAPROLE_RESEND_PARAM_UPDATE);
該過程抓包顯示如下:
從抓到的包中我們看到首先是S->M,即從設(shè)備發(fā)送連接參數(shù)更新請求,請求中帶有申請的連接參數(shù),然后M->S,即主設(shè)備返回連接參數(shù)更新響應(yīng),Result為0,表示同意修改更新。最后M->S發(fā)送Datatype為Control的鏈路層連接參數(shù)更新控制規(guī)程,攜帶同意的連接參數(shù),這樣,新的連接參數(shù)就會投入使用。
注意修改連接參數(shù)的時候要滿足一定的要求:
1.安卓設(shè)備作主設(shè)備時,連接參數(shù)滿足的要求見本篇博文第二節(jié)“連接參數(shù)介紹”中提到的內(nèi)容。另外實際開發(fā)過程中發(fā)現(xiàn)安卓設(shè)備作主設(shè)備時存在一個問題,就是部分安卓設(shè)備連接BLE設(shè)備之后,只能進行一次連接參數(shù)的修改。
2. 蘋果系統(tǒng)設(shè)備作主設(shè)備時,連接參數(shù)更新的要求比較苛刻,如下:
IntervalMax*(SlaveLatency+1)≤2seconds
IntervalMin≥20ms
IntervalMin+20ms≤IntervalMax
SlaveLatency≤4
connSupervisionTimeout≤6seconds
IntervalMax*(SlaveLatency+1)*3<connSupervisionTimeout
即:
最大連接間隔時間 *(從機延遲+1)≤2s
最小連接間隔時間 ≥20ms
最小連接間隔時間 +20ms≤最大連接間隔時間
從機延遲≤4
超時時間≤6s
最大連接間隔時間 *(從機延遲+1)*3<超時時間
所以如果你的BLE從設(shè)備需要被iOS主設(shè)備連接,那你的BLE從設(shè)備的默認申請的連接參數(shù)一定要滿足上述要求,并且連接過程中修改連接參數(shù)的時候也要滿足上述要求。
總結(jié)
以上是生活随笔為你收集整理的低功耗蓝牙BLE之连接事件、连接参数和更新方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 万科物业九项服务详情
- 下一篇: 广义牛顿二项式定理