1 Star 0 Fork 1

jackxiao / mynewt-newtmgr

forked from mirrors_apache / mynewt-newtmgr 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
ble_act.go 27.41 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package nmble
import (
"encoding/json"
"fmt"
"time"
log "github.com/sirupsen/logrus"
. "mynewt.apache.org/newtmgr/nmxact/bledefs"
"mynewt.apache.org/newtmgr/nmxact/nmxutil"
)
// Blocking
func connect(x *BleXport, bl *Listener, r *BleConnectReq) (uint16, error) {
const rspType = MSG_TYPE_CONNECT
j, err := json.Marshal(r)
if err != nil {
return 0, err
}
if err := x.Tx(j); err != nil {
return 0, err
}
// Give blehostd three seconds of leeway to tell us the connection attempt
// timed out.
rspTimeout := time.Duration(r.DurationMs+3000) * time.Millisecond
rspTmoChan := time.After(rspTimeout)
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return 0, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleConnectRsp:
bl.Acked = true
if msg.Status != 0 {
str := fmt.Sprintf("BLE connection attempt failed; "+
"status=%s (%d)",
ErrCodeToString(msg.Status), msg.Status)
log.Debugf(str)
return 0, nmxutil.NewBleHostError(msg.Status, str)
}
case *BleConnectEvt:
if msg.Status == 0 {
return msg.ConnHandle, nil
} else {
str := fmt.Sprintf("BLE connection attempt failed; "+
"status=%s (%d)",
ErrCodeToString(msg.Status), msg.Status)
log.Debugf(str)
return 0, nmxutil.NewBleHostError(msg.Status, str)
}
case *BleConnCancelEvt:
str := "BLE connection attempt cancelled"
log.Debugf(str)
return 0, fmt.Errorf("%s", str)
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
case _, ok := <-rspTmoChan:
if ok {
return 0, fmt.Errorf("Failed to connect to peer after %s",
rspTimeout.String())
}
rspTmoChan = nil
}
}
}
// Blocking
func terminate(x *BleXport, bl *Listener, r *BleTerminateReq) error {
const rspType = MSG_TYPE_TERMINATE
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleTerminateRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
} else {
return nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func connCancel(x *BleXport, bl *Listener, r *BleConnCancelReq) error {
const rspType = MSG_TYPE_CONN_CANCEL
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
// Allow 10 seconds for the controller to cancel the connection.
rspTimeout := 10 * time.Second
rspTmoChan := time.After(rspTimeout)
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleConnCancelRsp:
bl.Acked = true
switch msg.Status {
case 0:
// Cancel initiated. Await connect failure.
return nil
case ERR_CODE_EALREADY:
// No connect in progress. Pretend success.
return nil
default:
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
case _, ok := <-rspTmoChan:
if ok {
x.Restart("Failed to cancel connect after " + rspTimeout.String())
}
rspTmoChan = nil
}
}
}
// Blocking.
func discAllSvcs(x *BleXport, bl *Listener, r *BleDiscAllSvcsReq) (
[]*BleDiscSvc, error) {
const rspType = MSG_TYPE_DISC_ALL_SVCS
const evtType = MSG_TYPE_DISC_SVC_EVT
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.Tx(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
var svcs []*BleDiscSvc
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleDiscAllSvcsRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleDiscSvcEvt:
switch msg.Status {
case 0:
svcs = append(svcs, &msg.Svc)
case ERR_CODE_EDONE:
return svcs, nil
default:
return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func discSvcUuid(x *BleXport, bl *Listener, r *BleDiscSvcUuidReq) (
*BleDiscSvc, error) {
const rspType = MSG_TYPE_DISC_SVC_UUID
const evtType = MSG_TYPE_DISC_SVC_EVT
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.Tx(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
var svc *BleDiscSvc
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleDiscSvcUuidRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleDiscSvcEvt:
switch msg.Status {
case 0:
svc = &msg.Svc
case ERR_CODE_EDONE:
if svc == nil {
return nil, nmxutil.FmtBleHostError(
msg.Status,
"Peer doesn't support required service: %s",
r.Uuid.String())
}
return svc, nil
default:
return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func discAllChrs(x *BleXport, bl *Listener, r *BleDiscAllChrsReq) (
[]*BleDiscChr, error) {
const rspType = MSG_TYPE_DISC_ALL_CHRS
const evtType = MSG_TYPE_DISC_CHR_EVT
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.Tx(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
chrs := []*BleDiscChr{}
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleDiscAllChrsRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleDiscChrEvt:
switch msg.Status {
case 0:
chrs = append(chrs, &msg.Chr)
case ERR_CODE_EDONE:
return chrs, nil
default:
return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func discAllDscs(x *BleXport, bl *Listener, r *BleDiscAllDscsReq) (
[]*BleDiscDsc, error) {
const rspType = MSG_TYPE_DISC_ALL_DSCS
const evtType = MSG_TYPE_DISC_DSC_EVT
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.Tx(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
dscs := []*BleDiscDsc{}
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleDiscAllDscsRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleDiscDscEvt:
switch msg.Status {
case 0:
dscs = append(dscs, &msg.Dsc)
case ERR_CODE_EDONE:
return dscs, nil
default:
return nil, StatusError(MSG_OP_EVT, evtType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func write(x *BleXport, bl *Listener, r *BleWriteReq) error {
const rspType = MSG_TYPE_WRITE_CMD
const evtType = MSG_TYPE_WRITE_ACK_EVT
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleWriteRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleWriteAckEvt:
switch msg.Status {
case 0:
return nil
default:
return StatusError(MSG_OP_EVT, evtType, msg.Status)
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func writeCmd(x *BleXport, bl *Listener, r *BleWriteCmdReq) error {
const rspType = MSG_TYPE_WRITE_CMD
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleWriteCmdRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
} else {
return nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func notify(x *BleXport, bl *Listener, r *BleNotifyReq) error {
const rspType = MSG_TYPE_NOTIFY
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleNotifyRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
} else {
return nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func findChr(x *BleXport, bl *Listener, r *BleFindChrReq) (
uint16, uint16, error) {
const rspType = MSG_TYPE_NOTIFY
j, err := json.Marshal(r)
if err != nil {
return 0, 0, err
}
if err := x.Tx(j); err != nil {
return 0, 0, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return 0, 0, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleFindChrRsp:
bl.Acked = true
if msg.Status != 0 {
return 0, 0, StatusError(MSG_OP_RSP, rspType, msg.Status)
} else {
return msg.DefHandle, msg.ValHandle, nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking.
func exchangeMtu(x *BleXport, bl *Listener, r *BleExchangeMtuReq) (
int, error) {
const rspType = MSG_TYPE_EXCHANGE_MTU
const evtType = MSG_TYPE_MTU_CHANGE_EVT
j, err := json.Marshal(r)
if err != nil {
return 0, err
}
if err := x.Tx(j); err != nil {
return 0, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return 0, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleExchangeMtuRsp:
bl.Acked = true
if msg.Status != 0 {
return 0, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleMtuChangeEvt:
if msg.Status != 0 {
return 0, StatusError(MSG_OP_EVT, evtType, msg.Status)
} else {
return int(msg.Mtu), nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func actScan(x *BleXport, bl *Listener, r *BleScanReq) (
<-chan BleAdvReport, <-chan error, error) {
const rspType = MSG_TYPE_SCAN
j, err := json.Marshal(r)
if err != nil {
return nil, nil, err
}
if err := x.Tx(j); err != nil {
return nil, nil, err
}
ach := make(chan BleAdvReport)
ech := make(chan error)
nmxutil.Assert(bl != nil)
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
go func() {
defer close(ach)
defer close(ech)
for {
select {
case err := <-bl.ErrChan:
ech <- err
return
case bm, ok := <-bl.MsgChan:
if ok {
switch msg := bm.(type) {
case *BleScanRsp:
bl.Acked = true
if msg.Status != 0 {
ech <- StatusError(MSG_OP_RSP, rspType, msg.Status)
return
}
case *BleScanEvt:
r := BleAdvReportFromScanEvt(msg)
ach <- r
case *BleScanCompleteEvt:
if msg.Reason == 0 {
// On successful completion, just return and allow
// the ech channel to close.
return
} else {
ech <- StatusError(MSG_OP_RSP, rspType, msg.Reason)
return
}
default:
}
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}()
return ach, ech, nil
}
func scanCancel(x *BleXport, bl *Listener, r *BleScanCancelReq) error {
const rspType = MSG_TYPE_SCAN_CANCEL
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleScanCancelRsp:
bl.Acked = true
if msg.Status != 0 && msg.Status != ERR_CODE_EALREADY {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func connFind(x *BleXport, bl *Listener, r *BleConnFindReq) (
BleConnDesc, error) {
const rspType = MSG_TYPE_CONN_FIND
j, err := json.Marshal(r)
if err != nil {
return BleConnDesc{}, err
}
if err := x.Tx(j); err != nil {
return BleConnDesc{}, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return BleConnDesc{}, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleConnFindRsp:
bl.Acked = true
if msg.Status != 0 {
return BleConnDesc{},
StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return BleDescFromConnFindRsp(msg), nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Tells the host to reset the controller.
func reset(x *BleXport, bl *Listener, r *BleResetReq) error {
const rspType = MSG_TYPE_RESET
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.txNoSync(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch bm.(type) {
case *BleResetRsp:
bl.Acked = true
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
return fmt.Errorf("Blehostd timeout: %s",
MsgTypeToString(rspType))
}
}
}
}
// Blocking
func securityInitiate(x *BleXport, bl *Listener,
r *BleSecurityInitiateReq) error {
const rspType = MSG_TYPE_SECURITY_INITIATE
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleSecurityInitiateRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
} else {
return nil
}
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func smInjectIo(x *BleXport, bl *Listener, r *BleSmInjectIoReq) error {
const rspType = MSG_TYPE_SM_INJECT_IO
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleSmInjectIoRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking
func advStart(x *BleXport, bl *Listener, stopChan chan struct{},
r *BleAdvStartReq) (uint16, error) {
const rspType = MSG_TYPE_ADV_START
j, err := json.Marshal(r)
if err != nil {
return 0, err
}
if err := x.Tx(j); err != nil {
return 0, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return 0, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAdvStartRsp:
bl.Acked = true
if msg.Status != 0 {
return 0, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
case *BleConnectEvt:
if msg.Status == 0 {
return msg.ConnHandle, nil
} else {
str := fmt.Sprintf("BLE peer failed to connect to us; "+
"status=%s (%d)",
ErrCodeToString(msg.Status), msg.Status)
log.Debugf(str)
return 0, nmxutil.NewBleHostError(msg.Status, str)
}
case *BleAdvCompleteEvt:
str := fmt.Sprintf("Advertising stopped; reason=%s (%d)",
ErrCodeToString(msg.Reason), msg.Reason)
log.Debugf(str)
return 0, nmxutil.NewBleHostError(msg.Reason, str)
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
case <-stopChan:
return 0, fmt.Errorf("advertise aborted")
}
}
}
// Blocking
func advStop(x *BleXport, bl *Listener, r *BleAdvStopReq) error {
const rspType = MSG_TYPE_ADV_STOP
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAdvStopRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking
func advSetData(x *BleXport, bl *Listener, r *BleAdvSetDataReq) error {
const rspType = MSG_TYPE_ADV_SET_DATA
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAdvSetDataRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking
func advRspSetData(x *BleXport, bl *Listener, r *BleAdvRspSetDataReq) error {
const rspType = MSG_TYPE_ADV_RSP_SET_DATA
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.Tx(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAdvRspSetDataRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Blocking
func advFields(x *BleXport, bl *Listener, r *BleAdvFieldsReq) (
[]byte, error) {
const rspType = MSG_TYPE_ADV_FIELDS
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.Tx(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAdvFieldsRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return msg.Data.Bytes, nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func clearSvcs(x *BleXport, bl *Listener, r *BleClearSvcsReq) error {
const rspType = MSG_TYPE_CLEAR_SVCS
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.txNoSync(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleClearSvcsRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func addSvcs(x *BleXport, bl *Listener, r *BleAddSvcsReq) error {
const rspType = MSG_TYPE_ADD_SVCS
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.txNoSync(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAddSvcsRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func commitSvcs(x *BleXport, bl *Listener, r *BleCommitSvcsReq) (
[]BleRegSvc, error) {
const rspType = MSG_TYPE_COMMIT_SVCS
j, err := json.Marshal(r)
if err != nil {
return nil, err
}
if err := x.txNoSync(j); err != nil {
return nil, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return nil, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleCommitSvcsRsp:
bl.Acked = true
if msg.Status != 0 {
return nil, StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return msg.Svcs, nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func accessStatus(x *BleXport, bl *Listener, r *BleAccessStatusReq) error {
const rspType = MSG_TYPE_ACCESS_STATUS
j, err := json.Marshal(r)
if err != nil {
return err
}
x.Tx(j)
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleAccessStatusRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Asks the controller to generate a random address. This is done when the
// transport is starting up, and therefore does not require the transport to be
// synced. Only the transport should call this function.
func genRandAddr(x *BleXport, bl *Listener, r *BleGenRandAddrReq) (
BleAddr, error) {
const rspType = MSG_TYPE_GEN_RAND_ADDR
j, err := json.Marshal(r)
if err != nil {
return BleAddr{}, err
}
if err := x.txNoSync(j); err != nil {
return BleAddr{}, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return BleAddr{}, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleGenRandAddrRsp:
bl.Acked = true
if msg.Status != 0 {
return BleAddr{},
StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return msg.Addr, nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Configures the controller with the specified random address. This is done
// when the transport is starting up, and therefore does not require the
// transport to be synced. Only the transport should call this function.
func setRandAddr(x *BleXport, bl *Listener, r *BleSetRandAddrReq) error {
const rspType = MSG_TYPE_SET_RAND_ADDR
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.txNoSync(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleSetRandAddrRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
// Configures the host with the specified preferred ATT MTU. This is done
// when the transport is starting up, and therefore does not require the
// transport to be synced. Only the transport should call this function.
func setPreferredMtu(x *BleXport, bl *Listener,
r *BleSetPreferredMtuReq) error {
const rspType = MSG_TYPE_SET_PREFERRED_MTU
j, err := json.Marshal(r)
if err != nil {
return err
}
if err := x.txNoSync(j); err != nil {
return err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleSetPreferredMtuRsp:
bl.Acked = true
if msg.Status != 0 {
return StatusError(MSG_OP_RSP, rspType, msg.Status)
}
return nil
default:
}
case _, ok := <-bhdTmoChan:
if ok {
x.Restart("Blehostd timeout: " + MsgTypeToString(rspType))
}
bhdTmoChan = nil
}
}
}
func checkSync(x *BleXport, bl *Listener, r *BleSyncReq) (bool, error) {
const rspType = MSG_TYPE_SYNC
j, err := json.Marshal(r)
if err != nil {
return false, err
}
if err := x.txNoSync(j); err != nil {
return false, err
}
bhdTmoChan := bl.AfterTimeout(x.RspTimeout())
for {
select {
case err := <-bl.ErrChan:
return false, err
case bm := <-bl.MsgChan:
switch msg := bm.(type) {
case *BleSyncRsp:
bl.Acked = true
return msg.Synced, nil
}
case _, ok := <-bhdTmoChan:
if ok {
return false, fmt.Errorf("Blehostd timeout: %s",
MsgTypeToString(rspType))
}
}
}
}
1
https://gitee.com/cloud_vr_ar/mynewt-newtmgr.git
git@gitee.com:cloud_vr_ar/mynewt-newtmgr.git
cloud_vr_ar
mynewt-newtmgr
mynewt-newtmgr
691c1077103e

搜索帮助