1var app = getApp();
2var ble_util = require("../../utils/ble_util.js")
3var hex_util = require("../../utils/hex_util.js")
4
5Page({
6  data: {
7    ssid: '',
8    ssidList: [],
9    password: '',
10
11    net_config_devices: [],
12    selected_device_index: 0,
13
14    netCfgState: {
15      scanning: false,
16      configing: false,
17    },
18
19    wifiSelect: false,
20
21    netState: -1,
22    ipAddr: null
23  },
24
25  onLoad() {
26  },
27
28  async startNetConfigDevicesDiscovery() {
29    this.setData({ 'netCfgState.scanning': true })
30    this.setData({ net_config_devices: [] })
31
32    await ble_util.OpenBluetoothAdapter().catch(err => { console.error(err) })
33
34    let res;
35    for (let retry = 10; retry > 0; retry--) {
36      console.log(retry)
37      res = await ble_util.DiscoveryBLEDevice('FFA0') // TODO 传参数找
38
39      if (res && res.devices != null) {
40        console.log(res.devices)
41        this.setData({
42          net_config_devices: res.devices
43        })
44        break;
45      }
46    }
47
48    console.log(res)
49    if (res.devices == null)
50      my.alert({ content: res.content })
51    this.setData({ 'netCfgState.scanning': false })
52
53  },
54
55  bindDevicePickerChange(event) {
56    this.setData({
57      selected_device_index: event.detail.value,
58    });
59  },
60
61  async getWiFiList() {
62    if (this.data.net_config_devices.length == 0) {
63      my.alert({ content: "请选择目标设备" })
64    }
65
66    this.setData({ ssidList: [] })
67    my.showLoading({ content: "扫描中", mask: true });
68    my.connectBLEDevice({
69      deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
70      success: res => {
71        my.notifyBLECharacteristicValueChange({
72          state: true,
73          deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
74          serviceId: ble_util.UUID_VENDOR_SERVICE[app.globalData.sysname],
75          characteristicId: ble_util.UUID_VENDOR_CHAR_NOTIFY[app.globalData.sysname],
76          success: () => {
77            my.offBLECharacteristicValueChange();
78            let wifiListHexStr = ""
79            let headStr = "FFD"
80            let headNum = 0
81            my.onBLECharacteristicValueChange((res) => {
82              console.log(res)
83              console.log('得到响应数据 = ' + res.value);
84              console.log(hex_util.hexString2String(res.value))
85              if (res.value.indexOf(headStr) == 0) {
86                if (res.value.length > 4) {
87                  if (res.value[3] == ("" + headNum)) {
88                    wifiListHexStr += res.value.slice(4)
89                    headNum += 1
90                  } else {
91                    console.error("数据传输错误,请重试")
92                    my.hideLoading();
93                  }
94                } else {
95                  my.hideLoading();
96                  console.log(wifiListHexStr)
97                  console.log(hex_util.hexString2String(wifiListHexStr))
98                  let wifiListStr = hex_util.hexString2String(wifiListHexStr)
99                  this.setData({ ssidList: wifiListStr.slice(1).split(")(").slice(0, -2) })
100                  if (this.data.ssidList.length > 0) {
101                    my.hideLoading();
102                    this.setData({ wifiSelect: true })
103                  } else {
104                    my.hideLoading();
105                    my.showToast({
106                      type: 'fail',
107                      content: '未扫描到可用 Wi-Fi',
108                      duration: 2000,
109                    });
110                  }
111                }
112              }
113            });
114            console.log('监听成功');
115          },
116          fail: error => {
117            my.hideLoading();
118            console.log({ content: '监听失败' + JSON.stringify(error) });
119          },
120        });
121
122        my.writeBLECharacteristicValue({
123          deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
124          serviceId: ble_util.UUID_VENDOR_SERVICE[app.globalData.sysname],
125          characteristicId: ble_util.UUID_VENDOR_CHAR_WRITE[app.globalData.sysname],
126          value: "FFC0",
127          success: res => {
128            console.log(res);
129            var notifyCheckCnt = 5
130            var notifyCheckInt = setInterval(() => {
131              if (this.data.ipAddr == null) {
132                this.notifyCheckCnt = this.notifyCheckCnt - 1
133                console.log('notifyCheckCnt ' + this.notifyCheckCnt)
134                if (notifyCheckCnt < 0) {
135                  clearInterval(notifyCheckInt)
136                  this.setData({ 'netCfgState.configing': false })
137                  my.alert({ content: "配网失败,设备无回复" })
138                }
139              }
140            }, 1000)
141          },
142          fail: error => {
143            this.setData({ 'netCfgState.configing': false })
144            console.log(error);
145          },
146        });
147      },
148      fail: error => {
149        this.setData({ 'netCfgState.configing': false })
150        console.log(error);
151      },
152    })
153  },
154
155  async setNetConfig() {
156    if (this.data.ssid.length < 1) {
157      my.alert({ content: '请输入正确的SSID' })
158      return
159    }
160    if (this.data.password.length < 8) {
161      my.alert({ content: '请输入正确的密码' })
162      return
163    }
164
165    await ble_util.OpenBluetoothAdapter().catch(err => { console.error(err) })
166
167    this.setData({ 'netCfgState.configing': true })
168    await ble_util.DisconnectBLEDevice(this.data.net_config_devices[this.data.selected_device_index].deviceId).catch(err => { console.error(err) })
169    my.connectBLEDevice({
170      deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
171      success: res => {
172        console.log('connect with ' + this.data.net_config_devices[this.data.selected_device_index].deviceId + ' success')
173        console.log(res)
174        console.log(ble_util.UUID_VENDOR_SERVICE[app.globalData.sysname])
175
176        my.notifyBLECharacteristicValueChange({
177          state: true,
178          deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
179          serviceId: ble_util.UUID_VENDOR_SERVICE[app.globalData.sysname],
180          characteristicId: ble_util.UUID_VENDOR_CHAR_NOTIFY[app.globalData.sysname],
181          success: () => {
182            my.offBLECharacteristicValueChange();
183            my.onBLECharacteristicValueChange((res) => {
184              console.log('得到响应数据 = ' + res.value);
185              console.log(hex_util.hexString2String(res.value))
186              this.notifyFormat(res.value)
187            });
188            console.log('监听成功');
189          },
190          fail: error => {
191            this.setData({ 'netCfgState.configing': false })
192            console.log({ content: '监听失败' + JSON.stringify(error) });
193          },
194        });
195
196        my.writeBLECharacteristicValue({
197          deviceId: this.data.net_config_devices[this.data.selected_device_index].deviceId,
198          serviceId: ble_util.UUID_VENDOR_SERVICE[app.globalData.sysname],
199          characteristicId: ble_util.UUID_VENDOR_CHAR_WRITE[app.globalData.sysname],
200          value: this.genNetConfigPacket(this.data.ssid, this.data.password),
201          success: res => {
202            console.log(res);
203            console.log('写入数据成功!' + this.genNetConfigPacket(this.data.ssid, this.data.password));
204
205            // retry here
206            var notifyCheckCnt = 5
207            var notifyCheckInt = setInterval(() => {
208              if (this.data.ipAddr == null) {
209                notifyCheckCnt = notifyCheckCnt - 1
210                console.log('notifyCheckCnt ' + notifyCheckCnt)
211                if (notifyCheckCnt < 0) {
212                  clearInterval(notifyCheckInt)
213                  this.setData({ 'netCfgState.configing': false })
214                  my.alert({ content: "配网失败,设备无回复" })
215                } else if (this.data.netCfgState.configing == false) {
216                  clearInterval(notifyCheckInt)
217                }
218              }
219            }, 1000)
220          },
221          fail: error => {
222            this.setData({ 'netCfgState.configing': false })
223            console.log(error);
224          },
225        });
226      },
227      fail: error => {
228        this.setData({ 'netCfgState.configing': false })
229        console.log(error);
230      },
231    })
232  },
233
234  notifyFormat(str) {
235    if (str.length > 2) {
236      let maybeIp = hex_util.hexString2String(str)
237      console.log(maybeIp)
238      if (this.StrIsIp(maybeIp)) {
239        this.setData({
240          ipAddr: maybeIp
241        })
242        this.setData({ 'netCfgState.configing': false })
243      }
244    }
245  },
246
247  genNetConfigPacket(ssid, password) {
248    // [(num)ssid_len, (num)psd_len, (str)ssid, (str)psd] => acsii => hex str
249    // 9,               6,            'A','U'.. '9','1','4'...
250    // 06               09            4155524F5241393134323238383431
251    // console.log(this.stringToBytes(String.fromCharCode(ssid.length) + String.fromCharCode(password.length) + ssid + password))
252    let ret = "ffa0"
253    ret += ssid.length < 16 ? ('0' + (ssid.length).toString(16)) : ((ssid.length).toString(16))
254    ret += password.length < 16 ? ('0' + (password.length).toString(16)) : ((password.length).toString(16))
255    for (let i = 0; i < ssid.length; i++) {
256      ret += ssid.charCodeAt(i) < 16 ? ('0' + ssid.charCodeAt(i).toString(16)) : ssid.charCodeAt(i).toString(16);
257    }
258    for (let i = 0; i < password.length; i++) {
259      ret += password.charCodeAt(i) < 16 ? ('0' + password.charCodeAt(i).toString(16)) : password.charCodeAt(i).toString(16);
260    }
261    return ret
262  },
263
264  StrIsIp(str) {
265    return /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/.test(str)
266  },
267
268  ssidOnInput(e) {
269    this.setData({
270      ssid: e.detail.value
271    })
272  },
273
274  passwordOnInput(e) {
275    this.setData({
276      password: e.detail.value
277    })
278  },
279
280  bindSSIDPickerChange(event) {
281    console.log(event)
282    this.setData({
283      ssid: this.data.ssidList[event.detail.value]
284    })
285  },
286
287  wifiSelectCancel() {
288    this.setData({ wifiSelect: false })
289  },
290
291  wifiPickerOnChange(e) {
292    console.log(e)
293    this.wifiSelectIndex = e.detail.value
294  },
295
296  wifiSelectConform() {
297    this.setData({ wifiSelect: false, ssid: this.data.ssidList[this.wifiSelectIndex] })
298  },
299
300  onHide() {
301    my.closeBluetoothAdapter();
302  }
303
304});