| /** |
| * 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 ( |
| "fmt" |
| "sync" |
| "time" |
| |
| log "github.com/sirupsen/logrus" |
| |
| . "mynewt.apache.org/newtmgr/nmxact/bledefs" |
| "mynewt.apache.org/newtmgr/nmxact/nmxutil" |
| "mynewt.apache.org/newtmgr/nmxact/sesn" |
| ) |
| |
| const WRITE_CMD_BASE_SZ = 3 |
| const NOTIFY_CMD_BASE_SZ = 3 |
| |
| var nextSeq BleSeq = BLE_SEQ_MIN |
| var seqMtx sync.Mutex |
| |
| func NextSeq() BleSeq { |
| seqMtx.Lock() |
| defer seqMtx.Unlock() |
| |
| seq := nextSeq |
| nextSeq++ |
| if nextSeq >= BLE_SEQ_EVT_MIN { |
| nextSeq = BLE_SEQ_MIN |
| } |
| |
| return seq |
| } |
| |
| func BhdTimeoutError(rspType MsgType, seq BleSeq) error { |
| str := fmt.Sprintf( |
| "Timeout waiting for blehostd to send %s response (seq=%d)", |
| MsgTypeToString(rspType), seq) |
| |
| log.Debug(str) |
| |
| return nmxutil.NewXportError(str) |
| } |
| |
| func StatusError(op MsgOp, msgType MsgType, status int) error { |
| str := fmt.Sprintf("%s %s indicates error: %s (%d)", |
| MsgOpToString(op), |
| MsgTypeToString(msgType), |
| ErrCodeToString(status), |
| status) |
| |
| log.Debug(str) |
| return nmxutil.NewBleHostError(status, str) |
| } |
| |
| func BleDescFromConnFindRsp(r *BleConnFindRsp) BleConnDesc { |
| return BleConnDesc{ |
| ConnHandle: r.ConnHandle, |
| OwnIdAddrType: r.OwnIdAddrType, |
| OwnIdAddr: r.OwnIdAddr, |
| OwnOtaAddrType: r.OwnOtaAddrType, |
| OwnOtaAddr: r.OwnOtaAddr, |
| PeerIdAddrType: r.PeerIdAddrType, |
| PeerIdAddr: r.PeerIdAddr, |
| PeerOtaAddrType: r.PeerOtaAddrType, |
| PeerOtaAddr: r.PeerOtaAddr, |
| Role: r.Role, |
| Encrypted: r.Encrypted, |
| Authenticated: r.Authenticated, |
| Bonded: r.Bonded, |
| KeySize: r.KeySize, |
| } |
| } |
| |
| func BleAdvReportFromScanEvt(e *BleScanEvt) BleAdvReport { |
| return BleAdvReport{ |
| EventType: e.EventType, |
| Sender: BleDev{ |
| AddrType: e.AddrType, |
| Addr: e.Addr, |
| }, |
| Rssi: e.Rssi, |
| |
| Fields: BleAdvFields{ |
| Data: e.Data.Bytes, |
| |
| Flags: e.DataFlags, |
| Uuids16: e.DataUuids16, |
| Uuids16IsComplete: e.DataUuids16IsComplete, |
| Uuids32: e.DataUuids32, |
| Uuids32IsComplete: e.DataUuids32IsComplete, |
| Uuids128: e.DataUuids128, |
| Uuids128IsComplete: e.DataUuids128IsComplete, |
| Name: e.DataName, |
| NameIsComplete: e.DataNameIsComplete, |
| TxPwrLvl: e.DataTxPwrLvl, |
| SlaveItvlMin: e.DataSlaveItvlMin, |
| SlaveItvlMax: e.DataSlaveItvlMax, |
| SvcDataUuid16: e.DataSvcDataUuid16.Bytes, |
| PublicTgtAddrs: e.DataPublicTgtAddrs, |
| Appearance: e.DataAppearance, |
| AdvItvl: e.DataAdvItvl, |
| SvcDataUuid32: e.DataSvcDataUuid32.Bytes, |
| SvcDataUuid128: e.DataSvcDataUuid128.Bytes, |
| Uri: e.DataUri, |
| MfgData: e.DataMfgData.Bytes, |
| }, |
| } |
| } |
| |
| func NewBleConnectReq() *BleConnectReq { |
| return &BleConnectReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_CONNECT, |
| Seq: NextSeq(), |
| |
| OwnAddrType: BLE_ADDR_TYPE_PUBLIC, |
| PeerAddrType: BLE_ADDR_TYPE_PUBLIC, |
| PeerAddr: BleAddr{}, |
| |
| DurationMs: 30000, |
| ScanItvl: 0x0010, |
| ScanWindow: 0x0010, |
| ItvlMin: 24, |
| ItvlMax: 40, |
| Latency: 0, |
| SupervisionTimeout: 0x0200, |
| MinCeLen: 0x0010, |
| MaxCeLen: 0x0300, |
| } |
| } |
| |
| func NewBleTerminateReq() *BleTerminateReq { |
| return &BleTerminateReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_TERMINATE, |
| Seq: NextSeq(), |
| |
| ConnHandle: 0, |
| HciReason: 0, |
| } |
| } |
| |
| func NewBleConnCancelReq() *BleConnCancelReq { |
| return &BleConnCancelReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_CONN_CANCEL, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleDiscAllSvcsReq() *BleDiscAllSvcsReq { |
| return &BleDiscAllSvcsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_DISC_ALL_SVCS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleDiscSvcUuidReq() *BleDiscSvcUuidReq { |
| return &BleDiscSvcUuidReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_DISC_SVC_UUID, |
| Seq: NextSeq(), |
| |
| ConnHandle: 0, |
| Uuid: BleUuid{}, |
| } |
| } |
| |
| func NewBleDiscAllChrsReq() *BleDiscAllChrsReq { |
| return &BleDiscAllChrsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_DISC_ALL_CHRS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleDiscAllDscsReq() *BleDiscAllDscsReq { |
| return &BleDiscAllDscsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_DISC_ALL_DSCS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleExchangeMtuReq() *BleExchangeMtuReq { |
| return &BleExchangeMtuReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_EXCHANGE_MTU, |
| Seq: NextSeq(), |
| |
| ConnHandle: 0, |
| } |
| } |
| |
| func NewBleGenRandAddrReq() *BleGenRandAddrReq { |
| return &BleGenRandAddrReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_GEN_RAND_ADDR, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleSetRandAddrReq() *BleSetRandAddrReq { |
| return &BleSetRandAddrReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SET_RAND_ADDR, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleWriteCmdReq() *BleWriteCmdReq { |
| return &BleWriteCmdReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_WRITE_CMD, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleWriteReq() *BleWriteReq { |
| return &BleWriteReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_WRITE, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleScanReq() *BleScanReq { |
| return &BleScanReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SCAN, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleScanCancelReq() *BleScanCancelReq { |
| return &BleScanCancelReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SCAN_CANCEL, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleSetPreferredMtuReq() *BleSetPreferredMtuReq { |
| return &BleSetPreferredMtuReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SET_PREFERRED_MTU, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleConnFindReq() *BleConnFindReq { |
| return &BleConnFindReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_CONN_FIND, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewResetReq() *BleResetReq { |
| return &BleResetReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_RESET, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleSecurityInitiateReq() *BleSecurityInitiateReq { |
| return &BleSecurityInitiateReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SECURITY_INITIATE, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAdvFieldsReq() *BleAdvFieldsReq { |
| return &BleAdvFieldsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADV_FIELDS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAdvSetDataReq() *BleAdvSetDataReq { |
| return &BleAdvSetDataReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADV_SET_DATA, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAdvRspSetDataReq() *BleAdvRspSetDataReq { |
| return &BleAdvRspSetDataReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADV_RSP_SET_DATA, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAdvStartReq() *BleAdvStartReq { |
| return &BleAdvStartReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADV_START, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAdvStopReq() *BleAdvStopReq { |
| return &BleAdvStopReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADV_STOP, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleClearSvcsReq() *BleClearSvcsReq { |
| return &BleClearSvcsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_CLEAR_SVCS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleAddSvcsReq() *BleAddSvcsReq { |
| return &BleAddSvcsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ADD_SVCS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleCommitSvcsReq() *BleCommitSvcsReq { |
| return &BleCommitSvcsReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_COMMIT_SVCS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewAccessStatusReq() *BleAccessStatusReq { |
| return &BleAccessStatusReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_ACCESS_STATUS, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewNotifyReq() *BleNotifyReq { |
| return &BleNotifyReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_NOTIFY, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewFindChrReq() *BleFindChrReq { |
| return &BleFindChrReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_FIND_CHR, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewSyncReq() *BleSyncReq { |
| return &BleSyncReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SYNC, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func NewBleSmInjectIoReq() *BleSmInjectIoReq { |
| return &BleSmInjectIoReq{ |
| Op: MSG_OP_REQ, |
| Type: MSG_TYPE_SM_INJECT_IO, |
| Seq: NextSeq(), |
| } |
| } |
| |
| func ConnFindXact(x *BleXport, connHandle uint16) (BleConnDesc, error) { |
| r := NewBleConnFindReq() |
| r.ConnHandle = connHandle |
| |
| key := SeqKey(r.Seq) |
| bl, err := x.AddListener(key) |
| if err != nil { |
| return BleConnDesc{}, err |
| } |
| defer x.RemoveListener(bl) |
| |
| return connFind(x, bl, r) |
| } |
| |
| func GenRandAddrXact(x *BleXport) (BleAddr, error) { |
| r := NewBleGenRandAddrReq() |
| |
| key := SeqKey(r.Seq) |
| bl, err := x.AddListener(key) |
| if err != nil { |
| return BleAddr{}, err |
| } |
| defer x.RemoveListener(bl) |
| |
| return genRandAddr(x, bl, r) |
| } |
| |
| func SetRandAddrXact(x *BleXport, addr BleAddr) error { |
| r := NewBleSetRandAddrReq() |
| r.Addr = addr |
| |
| key := SeqKey(r.Seq) |
| bl, err := x.AddListener(key) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return setRandAddr(x, bl, r) |
| } |
| |
| func SetPreferredMtuXact(x *BleXport, mtu uint16) error { |
| r := NewBleSetPreferredMtuReq() |
| r.Mtu = mtu |
| |
| key := SeqKey(r.Seq) |
| bl, err := x.AddListener(key) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return setPreferredMtu(x, bl, r) |
| } |
| |
| func ResetXact(x *BleXport) error { |
| r := NewResetReq() |
| |
| key := SeqKey(r.Seq) |
| bl, err := x.AddListener(key) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return reset(x, bl, r) |
| } |
| |
| func ClearSvcsXact(x *BleXport) error { |
| r := NewBleClearSvcsReq() |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return clearSvcs(x, bl, r) |
| } |
| |
| func AddSvcsXact(x *BleXport, svcs []BleAddSvc) error { |
| r := NewBleAddSvcsReq() |
| r.Svcs = svcs |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return addSvcs(x, bl, r) |
| } |
| |
| func CommitSvcsXact(x *BleXport) ([]BleRegSvc, error) { |
| r := NewBleCommitSvcsReq() |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return nil, err |
| } |
| defer x.RemoveListener(bl) |
| |
| return commitSvcs(x, bl, r) |
| } |
| |
| func AccessStatusXact(x *BleXport, attStatus uint8, data []byte) error { |
| r := NewAccessStatusReq() |
| r.AttStatus = attStatus |
| r.Data.Bytes = data |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return accessStatus(x, bl, r) |
| } |
| |
| func NotifyXact(x *BleXport, connHandle uint16, attrHandle uint16, |
| data []byte) error { |
| |
| r := NewNotifyReq() |
| r.ConnHandle = connHandle |
| r.AttrHandle = attrHandle |
| r.Data.Bytes = data |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return err |
| } |
| defer x.RemoveListener(bl) |
| |
| return notify(x, bl, r) |
| } |
| |
| func FindChrXact(x *BleXport, svcUuid BleUuid, chrUuid BleUuid) ( |
| uint16, uint16, error) { |
| |
| r := NewFindChrReq() |
| r.SvcUuid = svcUuid |
| r.ChrUuid = chrUuid |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return 0, 0, err |
| } |
| defer x.RemoveListener(bl) |
| |
| return findChr(x, bl, r) |
| } |
| |
| func SyncXact(x *BleXport) (bool, error) { |
| r := NewSyncReq() |
| |
| bl, err := x.AddListener(SeqKey(r.Seq)) |
| if err != nil { |
| return false, err |
| } |
| |
| synced, err := checkSync(x, bl, r) |
| if err != nil { |
| return false, err |
| } |
| |
| return synced, nil |
| } |
| |
| func DiscoverDeviceWithName( |
| bx *BleXport, |
| ownAddrType BleAddrType, |
| timeout time.Duration, |
| name string) (*BleDev, error) { |
| |
| advPred := func(r BleAdvReport) bool { |
| return r.Fields.Name != nil && *r.Fields.Name == name |
| } |
| |
| return DiscoverDevice(bx, ownAddrType, timeout, advPred) |
| } |
| |
| func BleAdvFieldsToReq(f BleAdvFields) *BleAdvFieldsReq { |
| r := NewBleAdvFieldsReq() |
| |
| r.Flags = f.Flags |
| r.Uuids16 = f.Uuids16 |
| r.Uuids16IsComplete = f.Uuids16IsComplete |
| r.Uuids32 = f.Uuids32 |
| r.Uuids32IsComplete = f.Uuids32IsComplete |
| r.Uuids128 = f.Uuids128 |
| r.Uuids128IsComplete = f.Uuids128IsComplete |
| r.Name = f.Name |
| r.NameIsComplete = f.NameIsComplete |
| r.TxPwrLvl = f.TxPwrLvl |
| r.SlaveItvlMin = f.SlaveItvlMin |
| r.SlaveItvlMax = f.SlaveItvlMax |
| r.SvcDataUuid16 = BleBytes{f.SvcDataUuid16} |
| r.PublicTgtAddrs = f.PublicTgtAddrs |
| r.Appearance = f.Appearance |
| r.AdvItvl = f.AdvItvl |
| r.SvcDataUuid32 = BleBytes{f.SvcDataUuid32} |
| r.SvcDataUuid128 = BleBytes{f.SvcDataUuid128} |
| r.Uri = f.Uri |
| r.MfgData = BleBytes{f.MfgData} |
| |
| return r |
| } |
| |
| func BleSvcToAddSvc(svc BleSvc) BleAddSvc { |
| as := BleAddSvc{ |
| Uuid: svc.Uuid, |
| SvcType: svc.SvcType, |
| } |
| |
| for _, chr := range svc.Chrs { |
| ac := BleAddChr{ |
| Uuid: chr.Uuid, |
| Flags: chr.Flags, |
| MinKeySize: chr.MinKeySize, |
| } |
| |
| for _, dsc := range chr.Dscs { |
| ad := BleAddDsc{ |
| Uuid: dsc.Uuid, |
| AttFlags: dsc.AttFlags, |
| MinKeySize: dsc.MinKeySize, |
| } |
| |
| ac.Dscs = append(ac.Dscs, ad) |
| } |
| |
| as.Chrs = append(as.Chrs, ac) |
| } |
| |
| return as |
| } |
| |
| func GapService(devName string) BleSvc { |
| return BleSvc{ |
| Uuid: BleUuid{0x1800, [16]byte{}}, |
| SvcType: BLE_SVC_TYPE_PRIMARY, |
| Chrs: []BleChr{ |
| // Device name. |
| BleChr{ |
| Uuid: BleUuid{0x2a00, [16]byte{}}, |
| Flags: BLE_GATT_F_READ, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte(devName) |
| }, |
| }, |
| |
| // Appearance. |
| BleChr{ |
| Uuid: BleUuid{0x2a01, [16]byte{}}, |
| Flags: BLE_GATT_F_READ, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte{0, 0} |
| }, |
| }, |
| |
| // Peripheral privacy flag. |
| BleChr{ |
| Uuid: BleUuid{0x2a02, [16]byte{}}, |
| Flags: BLE_GATT_F_READ, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte{0} |
| }, |
| }, |
| |
| // Reconnection address. |
| BleChr{ |
| Uuid: BleUuid{0x2a03, [16]byte{}}, |
| Flags: BLE_GATT_F_READ, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte{0, 0, 0, 0, 0, 0} |
| }, |
| }, |
| |
| // Peripheral preferred connection parameters. |
| BleChr{ |
| Uuid: BleUuid{0x2a04, [16]byte{}}, |
| Flags: BLE_GATT_F_READ, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte{0, 0, 0, 0, 0, 0, 0, 0} |
| }, |
| }, |
| }, |
| } |
| } |
| |
| func GattService() BleSvc { |
| return BleSvc{ |
| Uuid: BleUuid{0x1801, [16]byte{}}, |
| SvcType: BLE_SVC_TYPE_PRIMARY, |
| Chrs: []BleChr{ |
| // Device name. |
| BleChr{ |
| Uuid: BleUuid{0x2a05, [16]byte{}}, |
| Flags: BLE_GATT_F_INDICATE, |
| MinKeySize: 0, |
| AccessCb: func(access BleGattAccess) (uint8, []byte) { |
| return 0, []byte{0, 0, 0, 0} |
| }, |
| }, |
| }, |
| } |
| } |
| |
| func BuildMgmtChrs(mgmtProto sesn.MgmtProto) (BleMgmtChrs, error) { |
| mgmtChrs := BleMgmtChrs{} |
| |
| nmpSvcUuid, _ := ParseUuid(NmpPlainSvcUuid) |
| nmpChrUuid, _ := ParseUuid(NmpPlainChrUuid) |
| |
| ompSvcUuid, _ := ParseUuid(OmpUnsecSvcUuid) |
| ompReqChrUuid, _ := ParseUuid(OmpUnsecReqChrUuid) |
| ompRspChrUuid, _ := ParseUuid(OmpUnsecRspChrUuid) |
| |
| resSvcUuid, _ := ParseUuid(IotivitySvcUuid) |
| resReqChrUuid, _ := ParseUuid(IotivityReqChrUuid) |
| resRspChrUuid, _ := ParseUuid(IotivityRspChrUuid) |
| |
| switch mgmtProto { |
| case sesn.MGMT_PROTO_NMP: |
| mgmtChrs.NmpReqChr = &BleChrId{nmpSvcUuid, nmpChrUuid} |
| mgmtChrs.NmpRspChr = &BleChrId{nmpSvcUuid, nmpChrUuid} |
| |
| case sesn.MGMT_PROTO_OMP: |
| mgmtChrs.NmpReqChr = &BleChrId{ompSvcUuid, ompReqChrUuid} |
| mgmtChrs.NmpRspChr = &BleChrId{ompSvcUuid, ompRspChrUuid} |
| |
| default: |
| return mgmtChrs, |
| fmt.Errorf("invalid management protocol: %+v", mgmtProto) |
| } |
| |
| mgmtChrs.ResReqChr = &BleChrId{resSvcUuid, resReqChrUuid} |
| mgmtChrs.ResRspChr = &BleChrId{resSvcUuid, resRspChrUuid} |
| |
| return mgmtChrs, nil |
| } |
| |
| func IsSecErr(err error) bool { |
| bhdErr := nmxutil.ToBleHost(err) |
| if bhdErr == nil { |
| return false |
| } |
| |
| switch bhdErr.Status - ERR_CODE_ATT_BASE { |
| case ERR_CODE_ATT_INSUFFICIENT_AUTHEN, |
| ERR_CODE_ATT_INSUFFICIENT_AUTHOR, |
| ERR_CODE_ATT_INSUFFICIENT_KEY_SZ, |
| ERR_CODE_ATT_INSUFFICIENT_ENC: |
| |
| return true |
| |
| default: |
| return false |
| } |
| } |
| |
| // Attempts to convert the given error to a BLE security error. The conversion |
| // succeeds if the error represents a pairing failure due to missing or |
| // mismatched key material. |
| func ToSecurityErr(err error) error { |
| bhe := nmxutil.ToBleHost(err) |
| if bhe == nil { |
| return nil |
| } |
| |
| code := ErrCodeToSmUs(bhe.Status) |
| if code == -1 { |
| code = ErrCodeToSmPeer(bhe.Status) |
| } |
| |
| switch code { |
| case ERR_CODE_SM_ERR_PASSKEY, |
| ERR_CODE_SM_ERR_OOB, |
| ERR_CODE_SM_ERR_CONFIRM_MISMATCH, |
| ERR_CODE_SM_ERR_UNSPECIFIED, |
| ERR_CODE_SM_ERR_DHKEY, |
| ERR_CODE_SM_ERR_NUMCMP: |
| return nmxutil.NewBleSecurityError(err.Error()) |
| |
| default: |
| return nil |
| } |
| } |