<template>
  <view>
    <button @click="getList">获取设备列表</button>
    <button @click="stopGetList">停止获取</button>
    <view v-if="showList">
      <button class="device" v-for="item in list"
              :key="item.deviceId" @click="connect(item)">{{item.name}}
        - {{item.pair ? '已配对' : '未配对'}}-{{item.sleep ? '休眠中' :
            '已唤醒'}}</button>
    </view>
    <view v-else>
      <button @click="getPublicKey">获取锁公钥</button>
      <button @click="getTest">获取锁私钥</button>
    </view>
  </view>
</template>

<script>
import crc from 'crc'

export default {
  data() {
    return {
      list: [],
      getting: false,
      // deviceId: '6C3CD148-F456-1C61-F35E-C176B0CC644A',
      // serviceId: '0000FFF0-0000-1000-8000-00805F9B34FB',
      // characteristicId1: '0000FFF1-0000-1000-8000-00805F9B34FB',
      // characteristicId2: '0000FFF2-0000-1000-8000-00805F9B34FB',
      deviceId: '',
      serviceId: '',
      characteristicId1: '',
      characteristicId2: '',
      lockId: '',
      showList: true,
      number: 1
    }
  },
  onLoad() {
    uni.openBluetoothAdapter({
      success(res) {
        console.log('初始化成功')
        console.log(res)
      },
      fail(res) {
        console.log('初始化失败')
        console.log(res)
      }
    })
  },
  onUnload() {
    uni.closeBluetoothAdapter({
      success(res) {
        console.log('关闭蓝牙成功')
        console.log(res)
      },
      fail(res) {
        console.log('关闭蓝牙失败')
        console.log(res)
      }
    })
  },
  methods: {
    GetCommKey() {
      const userId = 294

      let buffer = new ArrayBuffer(54)
      let binaryData = new Uint8Array(buffer)

      // 固定包头
      binaryData[0] = 0xEF
      binaryData[1] = 0x01
      binaryData[2] = 0xEE
      binaryData[3] = 0x02

      // 包类型 发送
      binaryData[4] = 0x01

      // 包序号
      binaryData[5] = this.number / 256
      binaryData[6] = this.number % 256
      this.number++

      // 包标识

    },
    getPublicKey() {
      let buffer = new ArrayBuffer(54)
      let binaryData = new Uint8Array(buffer)

      // 固定包头
      binaryData[0] = 0xEF
      binaryData[1] = 0x01
      binaryData[2] = 0xEE
      binaryData[3] = 0x02

      // 包类型 发送
      binaryData[4] = 0x01

      // 包序号
      binaryData[5] = this.number / 256
      binaryData[6] = this.number % 256
      this.number++

      // 包标识
      binaryData[7] = 0x20

      // 数据长度
      binaryData[8] = 42 / 256
      binaryData[9] = 42 % 256
      binaryData[10] = 42 / 256
      binaryData[11] = 42 % 256

      // 命令
      binaryData[12] = 0x3090 / 256
      binaryData[13] = 0x3090 % 256

      // // 设备ID
      for(let i=0; i < this.lockId.length; i++){
        binaryData[14 + i] = this.lockId.charCodeAt(i);
      }

      // crc

      let newBuffer = new ArrayBuffer(56)
      let newBinaryData = new Uint8Array(newBuffer)
      for(let i = 0; i < 54; i++){
        newBinaryData[i] = binaryData[i]
      }
      newBinaryData[54] = crc.crc16kermit(buffer) / 256
      newBinaryData[55] = crc.crc16kermit(buffer) % 256
      this.writeBLECharacteristicValue(newBuffer)
    },
    writeBLECharacteristicValue(data) {
      const that = this
      console.log('写入设备的设备 ID',that.deviceId)
      console.log('写入设备的serviceId',that.serviceId)
      console.log('写入设备的characteristicId',that.characteristicId2)
      console.log('写入设备的lockID',that.lockId)

      let Uint8ArrayData = new Uint8Array(data)

      const hexString = Array.from(Uint8ArrayData, byte =>
          byte.toString(10)).join(',')
      console.log('未加工的数据', hexString)

      for(let i = 0; i < Math.ceil(data.byteLength / 20); i++){
        let buffer = new ArrayBuffer(20)
        let binaryData = new Uint8Array(buffer)
        for(let j = 0; j < 20; j++){
          if(i * 20 + j < data.byteLength){
            binaryData[j] = Uint8ArrayData[i * 20 + j]
          }
        }
        uni.writeBLECharacteristicValue({
          deviceId: that.deviceId,
          serviceId: that.serviceId,
          characteristicId: that.characteristicId2,
          value: buffer,
          success(write) {
            const hexString = Array.from(binaryData, byte =>
                byte.toString(10)).join(',')
            console.log('写入的数据', hexString)
            console.log('写入成功')
          },
          fail(res) {
            console.log('写入失败')
            console.log(res)
          }
        })
      }
    },
    notifyBLECharacteristicValueChange() {
      const that = this
      uni.notifyBLECharacteristicValueChange({
        state: true,
        deviceId: that.deviceId,
        serviceId: that.serviceId,
        characteristicId: that.characteristicId1,
        type: 'notification',
        success(res) {
          console.log(res)
          uni.onBLECharacteristicValueChange(function (res) {
            console.log('设备特征值改变')
            console.log(res)
            let binaryData = new Uint8Array(res.value)
            const hexString = Array.from(binaryData, byte =>
                byte.toString(10)).join(',')
            console.log(hexString)
          })
        }
      })
    },
    connect(item) {
      const that = this
      if(item.pair) {
        return
      }
      uni.createBLEConnection({
        deviceId: item.deviceId,
        success(res) {
          console.log('连接成功')
          console.log(res)
          uni.getBLEDeviceServices({
            deviceId: item.deviceId,
            success(res) {
              console.log('获取服务成功')
              console.log(res.services)
              const uuid = res.services[0].uuid
              that.lockId = item.name
              console.log('锁ID', that.lockId)
              uni.getBLEDeviceCharacteristics({
                deviceId: item.deviceId,
                serviceId: uuid,
                success(res) {
                  console.log('获取特征值成功')
                  console.log(res)
                  that.deviceId = item.deviceId
                  that.serviceId = uuid
                  for (let i = 0; i < res.characteristics.length; i++) {
                    if (res.characteristics[i].uuid.indexOf("FFF1") !== -1) {
                      that.characteristicId1 = res.characteristics[i].uuid
                    }
                    if (res.characteristics[i].uuid.indexOf("FFF2") !== -1) {
                      that.characteristicId2 = res.characteristics[i].uuid
                    }
                  }
                  that.showList = false
                  that.notifyBLECharacteristicValueChange()
                  uni.showToast({
                    title: '数据获取成功',
                    icon: 'none',
                    duration: 2000
                  })
                },
                fail(res) {
                  console.log('获取特征值失败')
                  console.log(res)
                }
              })
            },
            fail(res) {
              console.log('获取服务失败')
              console.log(res)
            }
          })
        },
        fail(res) {
          console.log('连接失败')
          console.log(res)
        }
      })
    },
    startGetList() {
      const that = this
      this.getting = true
      console.log('开始监听蓝牙列表更新')
      uni.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: false,
        powerLevel: 'high',
        success: function (res) {
          // 更新列表
          console.log('列表发生变化', res)
          that.getList()
        }
      })
    },
    stopGetList(){
      const that = this
      uni.stopBluetoothDevicesDiscovery({
        success: function () {
          that.getting = false
          console.log('停止获取设备列表成功')
        }
      })
    },
    getList() {
      const that = this
      uni.getBluetoothDevices({
        success(res) {
          console.log('获取设备列表成功')
          console.log(res)
          that.list = []
          for(let i =0; i < res.devices.length; i++){
            if(res.devices[i]?.advertisServiceUUIDs) {
              const advertisServiceUUIDs =
                  res.devices[i]?.advertisServiceUUIDs[0]
              if(advertisServiceUUIDs &&
                  advertisServiceUUIDs.slice(2,8)==='758824'){
                res.devices[i].pair =
                    advertisServiceUUIDs.slice(30,32) === '01'
                res.devices[i].sleep =
                    advertisServiceUUIDs.slice(32,34) === '00'
                that.list.push(res.devices[i])
              }
            }
          }
          console.log(that.list)
          if(!that.getting) {
            that.startGetList()
          }
        },
        fail(res) {
          console.log('获取设备列表失败')
          console.log(res)
        }
      })
    }
  }
}
</script>

<style>
.device {
  text-align: center;
}
</style>
