slave.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. const uuid3 = '0C76801A-62EB-45E5-96A8-37C8882ABB2B'
  2. const serviceId = 'D0611E78-BBB4-4591-A5F8-487910AE4366'
  3. const characteristicId = '8667556C-9A37-4C91-84ED-54EE27D90049'
  4. // 上面需要配置主机的 serviceId 和 characteristicId
  5. // ArrayBuffer转16进制字符串示例
  6. // function ab2hex(buffer) {
  7. // const hexArr = Array.prototype.map.call(
  8. // new Uint8Array(buffer),
  9. // function (bit) {
  10. // return ('00' + bit.toString(16)).slice(-2)
  11. // }
  12. // )
  13. // return hexArr.join('')
  14. // }
  15. function inArray(arr, key, val) {
  16. for (let i = 0; i < arr.length; i++) {
  17. if (arr[i][key] === val) {
  18. return i
  19. }
  20. }
  21. return -1
  22. }
  23. // slave/slave.js
  24. Page({
  25. onShareAppMessage() {
  26. return {
  27. title: '蓝牙',
  28. path: 'packageAPI/pages/device/slave/slave'
  29. }
  30. },
  31. data: {
  32. theme: 'light',
  33. connects: [],
  34. servers: []
  35. },
  36. onLoad() {
  37. this.setData({
  38. theme: wx.getSystemInfoSync().theme || 'light'
  39. })
  40. if (wx.onThemeChange) {
  41. wx.onThemeChange(({theme}) => {
  42. this.setData({theme})
  43. })
  44. }
  45. wx.onBLEPeripheralConnectionStateChanged(res => {
  46. console.log('connect')
  47. const connects = this.data.connects
  48. const idx = inArray(connects, 'deviceId', res.deviceId)
  49. if (idx >= 0) {
  50. connects[idx] = res
  51. } else {
  52. connects.push(res)
  53. }
  54. this.setData({connects})
  55. })
  56. },
  57. openBluetoothAdapter() {
  58. // 初始化蓝牙模块
  59. wx.openBluetoothAdapter({
  60. mode: 'peripheral',
  61. success: (res) => {
  62. console.log('openBluetoothAdapter success', res)
  63. this.createBLEPeripheralServer()
  64. },
  65. fail: (res) => {
  66. console.log(res)
  67. wx.showToast({
  68. title: `创建失败 错误码: ${res.errCode}`,
  69. icon: 'none'
  70. })
  71. if (res.errCode === 10001) {
  72. wx.onBluetoothAdapterStateChange(function (res) {
  73. console.log('onBluetoothAdapterStateChange', res)
  74. if (res.available) {
  75. this.createBLEPeripheralServer()
  76. }
  77. })
  78. }
  79. }
  80. })
  81. },
  82. createBLEPeripheralServer() {
  83. //
  84. wx.createBLEPeripheralServer().then(res => {
  85. console.log('createBLEPeripheralServer', res)
  86. this.data.servers.push(res.server)
  87. this.server = res.server
  88. this.setData({
  89. serverId: this.server.serverId
  90. })
  91. wx.showToast({
  92. title: '创建 server ',
  93. })
  94. this.server.onCharacteristicReadRequest(res => {
  95. const {serviceId, characteristicId, callbackId} = res
  96. const buffer = new ArrayBuffer(1)
  97. const dataView = new DataView(buffer)
  98. const newValue = Math.ceil(Math.random() * 10)
  99. dataView.setUint8(0, newValue)
  100. console.log('onCharacteristicReadRequest', res, newValue)
  101. this.server.writeCharacteristicValue({
  102. serviceId,
  103. characteristicId,
  104. value: buffer,
  105. needNotify: true,
  106. callbackId
  107. })
  108. })
  109. // 监听收到数据
  110. this.server.onCharacteristicWriteRequest(res => {
  111. console.log('onCharacteristicWriteRequest', res)
  112. const {
  113. serviceId, characteristicId, value, callbackId
  114. } = res
  115. wx.showToast({
  116. title: '收到主机数据'
  117. })
  118. this.server.writeCharacteristicValue({
  119. serviceId,
  120. characteristicId,
  121. value,
  122. needNotify: true,
  123. callbackId
  124. })
  125. })
  126. return res
  127. }).catch(() => {})
  128. },
  129. closeServer() {
  130. if (this.server) {
  131. this.server.close()
  132. wx.showToast({
  133. title: '关闭 server',
  134. })
  135. }
  136. },
  137. chaneMode() {
  138. wx.navigateBack()
  139. },
  140. onConfirm(e) {
  141. console.log('onConfirm')
  142. const n = e.detail.value * 1
  143. const buffer = new ArrayBuffer(1)
  144. const dataView = new DataView(buffer)
  145. dataView.setUint8(0, n)
  146. if (!this.server) {
  147. wx.showModal({
  148. title: '请先创建server',
  149. })
  150. return
  151. }
  152. this.server.writeCharacteristicValue({
  153. serviceId,
  154. characteristicId,
  155. value: buffer,
  156. needNotify: true
  157. })
  158. wx.showModal({
  159. title: '写入成功',
  160. content: '请在主机查看'
  161. })
  162. },
  163. showInput() {
  164. this.setData({
  165. input: !this.data.input
  166. })
  167. },
  168. addService() {
  169. const buffer = new ArrayBuffer(1)
  170. const dataView = new DataView(buffer)
  171. dataView.setUint8(0, 2)
  172. const descriptorBuffer = new ArrayBuffer(1)
  173. const dataView2 = new DataView(descriptorBuffer)
  174. dataView2.setInt8(0, 3)
  175. const service = {
  176. uuid: serviceId,
  177. characteristics: [{
  178. uuid: characteristicId,
  179. properties: {
  180. write: true,
  181. read: true,
  182. notify: true,
  183. indicate: true
  184. },
  185. permission: {
  186. readable: true,
  187. writeable: true,
  188. readEncryptionRequired: true,
  189. writeEncryptionRequired: true
  190. },
  191. value: buffer,
  192. descriptors: [{
  193. uuid: uuid3,
  194. permission: {
  195. write: true,
  196. read: true
  197. },
  198. value: descriptorBuffer
  199. }]
  200. }]
  201. }
  202. if (!this.server) {
  203. wx.showModal({
  204. title: '请先创建server',
  205. })
  206. return
  207. }
  208. this.server.addService({
  209. service
  210. }).then(res => {
  211. console.log('add Service', res)
  212. wx.showToast({
  213. title: '创建服务',
  214. })
  215. return res
  216. }, (rej) => {
  217. console.log(rej)
  218. if (rej.errCode === 10001) {
  219. wx.showToast({
  220. title: '请打开蓝牙',
  221. })
  222. } else {
  223. wx.showModal({
  224. title: '创建失败',
  225. content: `错误码: ${rej.errCode}`
  226. })
  227. }
  228. }).catch(() => {})
  229. },
  230. removeService() {
  231. if (!this.server) return
  232. this.server.removeService({
  233. serviceId
  234. }).then(res => {
  235. wx.showToast({
  236. title: '关闭服务',
  237. })
  238. console.log('removeService', res)
  239. return res
  240. }).catch(() => {})
  241. },
  242. startAdvertising() {
  243. if (!this.server) {
  244. wx.showModal({
  245. title: '请先创建server',
  246. })
  247. return
  248. }
  249. const buffer = new ArrayBuffer(1)
  250. const dataView = new DataView(buffer)
  251. dataView.setInt8(0, 4)
  252. this.server.startAdvertising({
  253. advertiseRequest: {
  254. connectable: true,
  255. deviceName: 'sanford',
  256. serviceUuids: [serviceId],
  257. manufacturerData: [{
  258. manufacturerId: 'sanfordsun-pc0',
  259. manufacturerSpecificData: buffer
  260. }]
  261. },
  262. powerLevel: 'medium'
  263. }).then(res => {
  264. console.log('startAdvertising', res)
  265. wx.showToast({
  266. title: '开启广播',
  267. })
  268. return res
  269. }).catch(() => {})
  270. },
  271. stopAdvertising() {
  272. if (!this.server) {
  273. wx.showModal({
  274. title: '请先创建server',
  275. })
  276. return
  277. }
  278. this.server.stopAdvertising()
  279. wx.showToast({
  280. title: '关闭广播',
  281. })
  282. },
  283. closeBluetoothAdapter() {
  284. wx.showToast({
  285. title: '结束流程',
  286. })
  287. wx.closeBluetoothAdapter()
  288. },
  289. onUnload() {
  290. this.data.servers.forEach(() => {
  291. // server.close()
  292. })
  293. },
  294. })