nmxact/bledefs/bledefs.go (854 lines of code) (raw):

/** * 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 bledefs import ( "bytes" "encoding/json" "fmt" "strconv" "strings" ) const BLE_ATT_ATTR_MAX_LEN = 512 const BLE_ATT_MTU_DFLT = 23 const CccdUuid = 0x2902 const IotivitySvcUuid = "ade3d529-c784-4f63-a987-eb69f70ee816" const IotivityReqChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218" const IotivityRspChrUuid = "e9241982-4580-42c4-8831-95048216b256" const UnauthSvcUuid = "0c08c213-98ed-4e43-a499-7e1137c39567" const UnauthReqChrUuid = "69b8a928-2ab2-487b-923e-54ce53a18bc1" const UnauthRspChrUuid = "bca10aea-5df1-4248-b72b-f52955ad9c88" const SecureSvcUuid = 0xfe18 const SecureReqChrUuid = 0x1000 const SecureRspChrUuid = 0x1001 const NmpPlainSvcUuid = "8d53dc1d-1db7-4cd3-868b-8a527460aa84" const NmpPlainChrUuid = "da2e7828-fbce-4e01-ae9e-261174997c48" const OmpUnsecSvcUuid = "ade3d529-c784-4f63-a987-eb69f70ee816" const OmpUnsecReqChrUuid = "ad7b334f-4637-4b86-90b6-9d787f03d218" const OmpUnsecRspChrUuid = "e9241982-4580-42c4-8831-95048216b256" const OmpSecSvcUuid = SecureSvcUuid const OmpSecReqChrUuid = SecureReqChrUuid const OmpSecRspChrUuid = SecureRspChrUuid type BleAddrType int const ( BLE_ADDR_TYPE_PUBLIC BleAddrType = 0 BLE_ADDR_TYPE_RANDOM = 1 BLE_ADDR_TYPE_RPA_PUB = 2 BLE_ADDR_TYPE_RPA_RND = 3 ) var BleAddrTypeStringMap = map[BleAddrType]string{ BLE_ADDR_TYPE_PUBLIC: "public", BLE_ADDR_TYPE_RANDOM: "random", BLE_ADDR_TYPE_RPA_PUB: "rpa_pub", BLE_ADDR_TYPE_RPA_RND: "rpa_rnd", } func BleAddrTypeToString(addrType BleAddrType) string { s := BleAddrTypeStringMap[addrType] if s == "" { return "???" } return s } func BleAddrTypeFromString(s string) (BleAddrType, error) { for addrType, name := range BleAddrTypeStringMap { if s == name { return addrType, nil } } return BleAddrType(0), fmt.Errorf("Invalid BleAddrType string: %s", s) } func (a BleAddrType) MarshalJSON() ([]byte, error) { return json.Marshal(BleAddrTypeToString(a)) } func (a *BleAddrType) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleAddrTypeFromString(s) return err } type BleAddr struct { Bytes [6]byte } func ParseBleAddr(s string) (BleAddr, error) { ba := BleAddr{} toks := strings.Split(strings.ToLower(s), ":") if len(toks) != 6 { return ba, fmt.Errorf("invalid BLE addr string: %s", s) } for i, t := range toks { u64, err := strconv.ParseUint(t, 16, 8) if err != nil { return ba, err } ba.Bytes[i] = byte(u64) } return ba, nil } func (ba *BleAddr) String() string { var buf bytes.Buffer buf.Grow(len(ba.Bytes) * 3) for i, b := range ba.Bytes { if i != 0 { buf.WriteString(":") } fmt.Fprintf(&buf, "%02x", b) } return buf.String() } func (ba *BleAddr) MarshalJSON() ([]byte, error) { return json.Marshal(ba.String()) } func (ba *BleAddr) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } var err error *ba, err = ParseBleAddr(s) if err != nil { return err } return nil } type BleDev struct { AddrType BleAddrType Addr BleAddr } func (bd *BleDev) String() string { return fmt.Sprintf("%s,%s", BleAddrTypeToString(bd.AddrType), bd.Addr.String()) } type BleUuid16 uint16 func (bu16 *BleUuid16) String() string { return fmt.Sprintf("0x%04x", *bu16) } func ParseUuid16(s string) (BleUuid16, error) { val, err := strconv.ParseUint(s, 0, 16) if err != nil { return BleUuid16(0), fmt.Errorf("Invalid UUID: %s", s) } return BleUuid16(val), nil } type BleUuid128 [16]byte func (bu128 *BleUuid128) String() string { var buf bytes.Buffer buf.Grow(len(bu128)*2 + 3) for i, b := range bu128 { switch i { case 4, 6, 8, 10: buf.WriteString("-") } fmt.Fprintf(&buf, "%02x", b) } return buf.String() } func ParseUuid128(s string) (BleUuid128, error) { var bu128 BleUuid128 if len(s) != 36 { return bu128, fmt.Errorf("Invalid UUID: %s", s) } boff := 0 for i := 0; i < 36; { switch i { case 8, 13, 18, 23: if s[i] != '-' { return bu128, fmt.Errorf("Invalid UUID: %s", s) } i++ default: u64, err := strconv.ParseUint(s[i:i+2], 16, 8) if err != nil { return bu128, fmt.Errorf("Invalid UUID: %s", s) } bu128[boff] = byte(u64) i += 2 boff++ } } return bu128, nil } func (bu128 *BleUuid128) MarshalJSON() ([]byte, error) { return json.Marshal(bu128.String()) } func (bu128 *BleUuid128) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } var err error *bu128, err = ParseUuid128(s) if err != nil { return err } return nil } type BleUuid struct { // Set to 0 if the 128-bit UUID should be used. U16 BleUuid16 U128 BleUuid128 } func (bu *BleUuid) String() string { if bu.U16 != 0 { return bu.U16.String() } else { return bu.U128.String() } } func ParseUuid(uuidStr string) (BleUuid, error) { bu := BleUuid{} var err error // First, try to parse as a 16-bit UUID. bu.U16, err = ParseUuid16(uuidStr) if err == nil { return bu, nil } // Try to parse as a 128-bit UUID. bu.U128, err = ParseUuid128(uuidStr) if err == nil { return bu, nil } return bu, err } func NewBleUuid16(uuid16 uint16) BleUuid { return BleUuid{BleUuid16(uuid16), BleUuid128{}} } func (bu *BleUuid) MarshalJSON() ([]byte, error) { if bu.U16 != 0 { return json.Marshal(bu.U16) } else { return json.Marshal(bu.U128.String()) } } func (bu *BleUuid) UnmarshalJSON(data []byte) error { var err error // If the value is a string, try to parse a UUID from it. */ var s string if err := json.Unmarshal(data, &s); err == nil { *bu, err = ParseUuid(s) return err } // Not a string; maybe it's a raw 16-bit number. if err = json.Unmarshal(data, &bu.U16); err != nil { return err } return nil } func CompareUuids(a BleUuid, b BleUuid) int { if a.U16 != 0 || b.U16 != 0 { return int(a.U16) - int(b.U16) } else { return bytes.Compare(a.U128[:], b.U128[:]) } } type BleScanFilterPolicy int const ( BLE_SCAN_FILT_NO_WL BleScanFilterPolicy = 0 BLE_SCAN_FILT_USE_WL = 1 BLE_SCAN_FILT_NO_WL_INITA = 2 BLE_SCAN_FILT_USE_WL_INITA = 3 ) var BleScanFilterPolicyStringMap = map[BleScanFilterPolicy]string{ BLE_SCAN_FILT_NO_WL: "no_wl", BLE_SCAN_FILT_USE_WL: "use_wl", BLE_SCAN_FILT_NO_WL_INITA: "no_wl_inita", BLE_SCAN_FILT_USE_WL_INITA: "use_wl_inita", } func BleScanFilterPolicyToString(filtPolicy BleScanFilterPolicy) string { s := BleScanFilterPolicyStringMap[filtPolicy] if s == "" { return "???" } return s } func BleScanFilterPolicyFromString(s string) (BleScanFilterPolicy, error) { for filtPolicy, name := range BleScanFilterPolicyStringMap { if s == name { return filtPolicy, nil } } return BleScanFilterPolicy(0), fmt.Errorf("Invalid BleScanFilterPolicy string: %s", s) } func (a BleScanFilterPolicy) MarshalJSON() ([]byte, error) { return json.Marshal(BleScanFilterPolicyToString(a)) } func (a *BleScanFilterPolicy) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleScanFilterPolicyFromString(s) return err } type BleAdvEventType int const ( BLE_ADV_EVENT_IND BleAdvEventType = 0 BLE_ADV_EVENT_DIRECT_IND_HD = 1 BLE_ADV_EVENT_SCAN_IND = 2 BLE_ADV_EVENT_NONCONN_IND = 3 BLE_ADV_EVENT_DIRECT_IND_LD = 4 ) var BleAdvEventTypeStringMap = map[BleAdvEventType]string{ BLE_ADV_EVENT_IND: "ind", BLE_ADV_EVENT_DIRECT_IND_HD: "direct_ind_hd", BLE_ADV_EVENT_SCAN_IND: "scan_ind", BLE_ADV_EVENT_NONCONN_IND: "nonconn_ind", BLE_ADV_EVENT_DIRECT_IND_LD: "direct_ind_ld", } func BleAdvEventTypeToString(advEventType BleAdvEventType) string { s := BleAdvEventTypeStringMap[advEventType] if s == "" { return "???" } return s } func BleAdvEventTypeFromString(s string) (BleAdvEventType, error) { for advEventType, name := range BleAdvEventTypeStringMap { if s == name { return advEventType, nil } } return BleAdvEventType(0), fmt.Errorf("Invalid BleAdvEventType string: %s", s) } func (a BleAdvEventType) MarshalJSON() ([]byte, error) { return json.Marshal(BleAdvEventTypeToString(a)) } func (a *BleAdvEventType) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleAdvEventTypeFromString(s) return err } type BleAdvConnMode int const ( BLE_ADV_CONN_MODE_NON BleAdvConnMode = iota BLE_ADV_CONN_MODE_DIR BLE_ADV_CONN_MODE_UND ) var BleAdvConnModeStringMap = map[BleAdvConnMode]string{ BLE_ADV_CONN_MODE_NON: "non", BLE_ADV_CONN_MODE_DIR: "dir", BLE_ADV_CONN_MODE_UND: "und", } func BleAdvConnModeToString(connMode BleAdvConnMode) string { s := BleAdvConnModeStringMap[connMode] if s == "" { return "???" } return s } func BleAdvConnModeFromString(s string) (BleAdvConnMode, error) { for advConnMode, name := range BleAdvConnModeStringMap { if s == name { return advConnMode, nil } } return BleAdvConnMode(0), fmt.Errorf("Invalid BleAdvConnMode string: %s", s) } func (a BleAdvConnMode) MarshalJSON() ([]byte, error) { return json.Marshal(BleAdvConnModeToString(a)) } func (a *BleAdvConnMode) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleAdvConnModeFromString(s) return err } type BleAdvDiscMode int const ( BLE_ADV_DISC_MODE_NON BleAdvDiscMode = iota BLE_ADV_DISC_MODE_LTD BLE_ADV_DISC_MODE_GEN ) var BleAdvDiscModeStringMap = map[BleAdvDiscMode]string{ BLE_ADV_DISC_MODE_NON: "non", BLE_ADV_DISC_MODE_LTD: "ltd", BLE_ADV_DISC_MODE_GEN: "gen", } func BleAdvDiscModeToString(discMode BleAdvDiscMode) string { s := BleAdvDiscModeStringMap[discMode] if s == "" { return "???" } return s } func BleAdvDiscModeFromString(s string) (BleAdvDiscMode, error) { for advDiscMode, name := range BleAdvDiscModeStringMap { if s == name { return advDiscMode, nil } } return BleAdvDiscMode(0), fmt.Errorf("Invalid BleAdvDiscMode string: %s", s) } func (a BleAdvDiscMode) MarshalJSON() ([]byte, error) { return json.Marshal(BleAdvDiscModeToString(a)) } func (a *BleAdvDiscMode) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleAdvDiscModeFromString(s) return err } type BleAdvFilterPolicy int const ( BLE_ADV_FILTER_POLICY_NONE BleAdvFilterPolicy = iota BLE_ADV_FILTER_POLICY_SCAN BLE_ADV_FILTER_POLICY_CONN BLE_ADV_FILTER_POLICY_BOTH ) var BleAdvFilterPolicyStringMap = map[BleAdvFilterPolicy]string{ BLE_ADV_FILTER_POLICY_NONE: "none", BLE_ADV_FILTER_POLICY_SCAN: "scan", BLE_ADV_FILTER_POLICY_CONN: "conn", BLE_ADV_FILTER_POLICY_BOTH: "both", } func BleAdvFilterPolicyToString(discMode BleAdvFilterPolicy) string { s := BleAdvFilterPolicyStringMap[discMode] if s == "" { return "???" } return s } func BleAdvFilterPolicyFromString(s string) (BleAdvFilterPolicy, error) { for advFilterPolicy, name := range BleAdvFilterPolicyStringMap { if s == name { return advFilterPolicy, nil } } return BleAdvFilterPolicy(0), fmt.Errorf("Invalid BleAdvFilterPolicy string: %s", s) } func (a BleAdvFilterPolicy) MarshalJSON() ([]byte, error) { return json.Marshal(BleAdvFilterPolicyToString(a)) } func (a *BleAdvFilterPolicy) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleAdvFilterPolicyFromString(s) return err } type BleAdvFields struct { Data []byte // Each field is only present if the sender included it in its // advertisement. Flags *uint8 Uuids16 []BleUuid16 Uuids16IsComplete bool Uuids32 []uint32 Uuids32IsComplete bool Uuids128 []BleUuid128 Uuids128IsComplete bool Name *string NameIsComplete bool TxPwrLvl *int8 SlaveItvlMin *uint16 SlaveItvlMax *uint16 SvcDataUuid16 []byte PublicTgtAddrs []BleAddr Appearance *uint16 AdvItvl *uint16 SvcDataUuid32 []byte SvcDataUuid128 []byte Uri *string MfgData []byte } type BleAdvReport struct { // These fields are always present. EventType BleAdvEventType Sender BleDev Rssi int8 Fields BleAdvFields } type BleAdvRptFn func(r BleAdvReport) type BleAdvPredicate func(adv BleAdvReport) bool type BleRole int const ( BLE_ROLE_MASTER BleRole = iota BLE_ROLE_SLAVE ) type BleConnDesc struct { ConnHandle uint16 OwnIdAddrType BleAddrType OwnIdAddr BleAddr OwnOtaAddrType BleAddrType OwnOtaAddr BleAddr PeerIdAddrType BleAddrType PeerIdAddr BleAddr PeerOtaAddrType BleAddrType PeerOtaAddr BleAddr Role BleRole Encrypted bool Authenticated bool Bonded bool KeySize int } func (d *BleConnDesc) String() string { return fmt.Sprintf("conn_handle=%d "+ "own_id_addr=%s,%s own_ota_addr=%s,%s "+ "peer_id_addr=%s,%s peer_ota_addr=%s,%s", d.ConnHandle, BleAddrTypeToString(d.OwnIdAddrType), d.OwnIdAddr.String(), BleAddrTypeToString(d.OwnOtaAddrType), d.OwnOtaAddr.String(), BleAddrTypeToString(d.PeerIdAddrType), d.PeerIdAddr.String(), BleAddrTypeToString(d.PeerOtaAddrType), d.PeerOtaAddr.String()) } type BleEncryptWhen int const ( BLE_ENCRYPT_NEVER BleEncryptWhen = iota BLE_ENCRYPT_AS_REQD BLE_ENCRYPT_ALWAYS ) type BleGattOp int const ( BLE_GATT_ACCESS_OP_READ_CHR BleGattOp = 0 BLE_GATT_ACCESS_OP_WRITE_CHR = 1 BLE_GATT_ACCESS_OP_READ_DSC = 2 BLE_GATT_ACCESS_OP_WRITE_DSC = 3 ) var BleGattOpStringMap = map[BleGattOp]string{ BLE_GATT_ACCESS_OP_READ_CHR: "read_chr", BLE_GATT_ACCESS_OP_WRITE_CHR: "write_chr", BLE_GATT_ACCESS_OP_READ_DSC: "read_dsc", BLE_GATT_ACCESS_OP_WRITE_DSC: "write_dsc", } func BleGattOpToString(op BleGattOp) string { s := BleGattOpStringMap[op] if s == "" { return "???" } return s } func BleGattOpFromString(s string) (BleGattOp, error) { for op, name := range BleGattOpStringMap { if s == name { return op, nil } } return BleGattOp(0), fmt.Errorf("Invalid BleGattOp string: %s", s) } type BleSvcType int const ( BLE_SVC_TYPE_PRIMARY BleSvcType = iota BLE_SVC_TYPE_SECONDARY ) var BleSvcTypeStringMap = map[BleSvcType]string{ BLE_SVC_TYPE_PRIMARY: "primary", BLE_SVC_TYPE_SECONDARY: "secondary", } func BleSvcTypeToString(svcType BleSvcType) string { s := BleSvcTypeStringMap[svcType] if s == "" { return "???" } return s } func BleSvcTypeFromString(s string) (BleSvcType, error) { for svcType, name := range BleSvcTypeStringMap { if s == name { return svcType, nil } } return BleSvcType(0), fmt.Errorf("Invalid BleSvcType string: %s", s) } func (a BleSvcType) MarshalJSON() ([]byte, error) { return json.Marshal(BleSvcTypeToString(a)) } func (a *BleSvcType) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleSvcTypeFromString(s) return err } type BleChrFlags int const ( BLE_GATT_F_BROADCAST BleChrFlags = 0x0001 BLE_GATT_F_READ = 0x0002 BLE_GATT_F_WRITE_NO_RSP = 0x0004 BLE_GATT_F_WRITE = 0x0008 BLE_GATT_F_NOTIFY = 0x0010 BLE_GATT_F_INDICATE = 0x0020 BLE_GATT_F_AUTH_SIGN_WRITE = 0x0040 BLE_GATT_F_RELIABLE_WRITE = 0x0080 BLE_GATT_F_AUX_WRITE = 0x0100 BLE_GATT_F_READ_ENC = 0x0200 BLE_GATT_F_READ_AUTHEN = 0x0400 BLE_GATT_F_READ_AUTHOR = 0x0800 BLE_GATT_F_WRITE_ENC = 0x1000 BLE_GATT_F_WRITE_AUTHEN = 0x2000 BLE_GATT_F_WRITE_AUTHOR = 0x4000 ) type BleAttFlags int const ( BLE_ATT_F_READ BleAttFlags = 0x01 BLE_ATT_F_WRITE = 0x02 BLE_ATT_F_READ_ENC = 0x04 BLE_ATT_F_READ_AUTHEN = 0x08 BLE_ATT_F_READ_AUTHOR = 0x10 BLE_ATT_F_WRITE_ENC = 0x20 BLE_ATT_F_WRITE_AUTHEN = 0x40 BLE_ATT_F_WRITE_AUTHOR = 0x80 ) type BleDiscChrProperties int const ( BLE_DISC_CHR_PROP_BROADCAST BleDiscChrProperties = 0x01 BLE_DISC_CHR_PROP_READ = 0x02 BLE_DISC_CHR_PROP_WRITE_NO_RSP = 0x04 BLE_DISC_CHR_PROP_WRITE = 0x08 BLE_DISC_CHR_PROP_NOTIFY = 0x10 BLE_DISC_CHR_PROP_INDICATE = 0x20 BLE_DISC_CHR_PROP_AUTH_SIGN_WRITE = 0x40 BLE_DISC_CHR_PROP_EXTENDED = 0x80 ) type BleGattAccess struct { Op BleGattOp ConnHandle uint16 SvcUuid BleUuid ChrUuid BleUuid Data []byte } type BleGattAccessFn func(access BleGattAccess) (uint8, []byte) type BleDsc struct { Uuid BleUuid AttFlags BleAttFlags MinKeySize int } type BleChr struct { Uuid BleUuid Flags BleChrFlags MinKeySize int AccessCb BleGattAccessFn Dscs []BleDsc } type BleSvc struct { Uuid BleUuid SvcType BleSvcType Chrs []BleChr } type BleChrId struct { SvcUuid BleUuid ChrUuid BleUuid } func (b *BleChrId) String() string { return fmt.Sprintf("s=%s c=%s", b.SvcUuid.String(), b.ChrUuid.String()) } func CompareChrIds(a BleChrId, b BleChrId) int { if rc := CompareUuids(a.SvcUuid, b.SvcUuid); rc != 0 { return rc } if rc := CompareUuids(a.ChrUuid, b.ChrUuid); rc != 0 { return rc } return 0 } type BleMgmtChrs struct { NmpReqChr *BleChrId NmpRspChr *BleChrId ResReqChr *BleChrId ResRspChr *BleChrId } type BleSmAction int const ( BLE_SM_ACTION_OOB BleSmAction = iota BLE_SM_ACTION_INPUT BLE_SM_ACTION_DISP BLE_SM_ACTION_NUMCMP ) var BleSmActionStringMap = map[BleSmAction]string{ BLE_SM_ACTION_OOB: "oob", BLE_SM_ACTION_INPUT: "input", BLE_SM_ACTION_DISP: "disp", BLE_SM_ACTION_NUMCMP: "numcmp", } func BleSmActionToString(smAction BleSmAction) string { s := BleSmActionStringMap[smAction] if s == "" { return "???" } return s } func BleSmActionFromString(s string) (BleSmAction, error) { for smAction, name := range BleSmActionStringMap { if s == name { return smAction, nil } } return BleSmAction(0), fmt.Errorf("Invalid BleSmAction string: %s", s) } func (io BleSmAction) String() string { return BleSmActionToString(io) } func (a BleSmAction) MarshalJSON() ([]byte, error) { return json.Marshal(BleSmActionToString(a)) } func (a *BleSmAction) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleSmActionFromString(s) return err } type BleSmIoCap int const ( BLE_SM_IO_CAP_DISP_ONLY BleSmIoCap = iota BLE_SM_IO_CAP_DISP_YES_NO BLE_SM_IO_CAP_KEYBOARD_ONLY BLE_SM_IO_CAP_NO_IO BLE_SM_IO_CAP_KEYBOARD_DISP ) var BleSmIoCapStringMap = map[BleSmIoCap]string{ BLE_SM_IO_CAP_DISP_ONLY: "disp_only", BLE_SM_IO_CAP_DISP_YES_NO: "disp_yes_no", BLE_SM_IO_CAP_KEYBOARD_ONLY: "keyboard_only", BLE_SM_IO_CAP_NO_IO: "no_io", BLE_SM_IO_CAP_KEYBOARD_DISP: "keyboard_disp", } func BleSmIoCapToString(smAction BleSmIoCap) string { s := BleSmIoCapStringMap[smAction] if s == "" { return "???" } return s } func BleSmIoCapFromString(s string) (BleSmIoCap, error) { for smAction, name := range BleSmIoCapStringMap { if s == name { return smAction, nil } } return BleSmIoCap(0), fmt.Errorf("Invalid BleSmIoCap string: %s", s) } func (io BleSmIoCap) String() string { return BleSmIoCapToString(io) } func (a BleSmIoCap) MarshalJSON() ([]byte, error) { return json.Marshal(BleSmIoCapToString(a)) } func (a *BleSmIoCap) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleSmIoCapFromString(s) return err } type BleSmKeyDist int const ( BLE_SM_KEY_DIST_ENC BleSmKeyDist = iota BLE_SM_KEY_DIST_ID BLE_SM_KEY_DIST_SIGN BLE_SM_KEY_DIST_LINK ) var BleSmKeyDistStringMap = map[BleSmKeyDist]string{ BLE_SM_KEY_DIST_ENC: "enc", BLE_SM_KEY_DIST_ID: "id", BLE_SM_KEY_DIST_SIGN: "sign", BLE_SM_KEY_DIST_LINK: "link", } func BleSmKeyDistToString(smAction BleSmKeyDist) string { s := BleSmKeyDistStringMap[smAction] if s == "" { return "???" } return s } func BleSmKeyDistFromString(s string) (BleSmKeyDist, error) { for smAction, name := range BleSmKeyDistStringMap { if s == name { return smAction, nil } } return BleSmKeyDist(0), fmt.Errorf("Invalid BleSmKeyDist string: %s", s) } func (io BleSmKeyDist) String() string { return BleSmKeyDistToString(io) } func (a BleSmKeyDist) MarshalJSON() ([]byte, error) { return json.Marshal(BleSmKeyDistToString(a)) } func (a *BleSmKeyDist) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleSmKeyDistFromString(s) return err } type BleSmAuthReq int const ( BLE_SM_AUTHREQ_BOND BleSmAuthReq = iota BLE_SM_AUTHREQ_MITM BLE_SM_AUTHREQ_SC BLE_SM_AUTHREQ_KEYPRESS ) var BleSmAuthReqStringMap = map[BleSmAuthReq]string{ BLE_SM_AUTHREQ_BOND: "bond", BLE_SM_AUTHREQ_MITM: "mitm", BLE_SM_AUTHREQ_SC: "sc", BLE_SM_AUTHREQ_KEYPRESS: "keypress", } func BleSmAuthReqToString(smAction BleSmAuthReq) string { s := BleSmAuthReqStringMap[smAction] if s == "" { return "???" } return s } func BleSmAuthReqFromString(s string) (BleSmAuthReq, error) { for smAction, name := range BleSmAuthReqStringMap { if s == name { return smAction, nil } } return BleSmAuthReq(0), fmt.Errorf("Invalid BleSmAuthReq string: %s", s) } func (io BleSmAuthReq) String() string { return BleSmAuthReqToString(io) } func (a BleSmAuthReq) MarshalJSON() ([]byte, error) { return json.Marshal(BleSmAuthReqToString(a)) } func (a *BleSmAuthReq) UnmarshalJSON(data []byte) error { var err error var s string if err := json.Unmarshal(data, &s); err != nil { return err } *a, err = BleSmAuthReqFromString(s) return err } type BlePairCfg struct { IoCap BleSmIoCap Oob bool Bonding bool Mitm bool Sc bool Keypress bool OurKeyDist BleSmKeyDist TheirKeyDist BleSmKeyDist }