'Web bluetooth sending and receiveing issue#2
My issue is simple. Can receive data, cannot send data.
I try to send and receive to and from BLE device by web bluetooth. This app runs on Android. This device has a pincode authentication.(I can't disable pincode, just can change) When I run requestDevice() api function, I get this exception: DOM exception: GATT operation is not permitted. I went through web bluetooth api about this exception and this doesn't help me. Even though this error occurs, I can receive from BLE device but not send data(seems not happening). Here is my code.
import React, { useEffect, useState } from "react";
import { Button, Col, Container, Row } from "reactstrap";
import "./App.css";
import Swal from 'sweetalert2';
import { NotificationContainer, NotificationManager } from 'react-notifications';
let bluetoothDevice, sendCharacteristic, receiveCharacteristic;
let primaryServiceUuid = null;
let receiveCharUuid = null;
let sendCharUuid = null;
const App = () => {
const [isEnabled, setIsEnabled] = useState(true);
useEffect(() => {
navigator.bluetooth.getAvailability().then(available => {
if (available) {
NotificationManager.success('Success to access Bluetooth');
setIsEnabled(true);
}
else {
Swal.fire({
title: 'Sorry, Your device is not Bluetoothable.',
icon: 'error',
confirmButtonColor: 'rgb(200, 35, 51)'
});
setIsEnabled(false);
}
});
}, []);
const onClickConnect = async () => {
let serviceUuid = document.getElementById('serviceUuid').value;
if(!serviceUuid) return NotificationManager.error('Please fill Service UUID.');
if (serviceUuid.startsWith('0x')) {
primaryServiceUuid = parseInt(serviceUuid);
} else return NotificationManager.error('Wrong Format: Service UUID.');
let sendUuid = document.getElementById('sendUuid').value;
if(!sendUuid) return NotificationManager.error('Please fill Send UUID.');
if (sendUuid.startsWith('0x')) {
sendCharUuid = parseInt(sendUuid);
} else return NotificationManager.error('Wrong Format: Send UUID.');
// let receiveUuid = document.getElementById('receiveUuid').value;
// if(!receiveUuid) return NotificationManager.error('Please fill Recieve UUID.');
// if (receiveUuid.startsWith('0x')) {
// receiveCharUuid = parseInt(sendUuid);
// };
bluetoothDevice = null;
bluetoothDevice = await navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: [primaryServiceUuid]
});
const server = await bluetoothDevice.gatt.connect();
if (!server) {
return NotificationManager.error('Whoops, failed. Retry: server not found');
}
const service = await server.getPrimaryService(primaryServiceUuid);
if (!service) {
return NotificationManager.error('Whoops, failed. Retry: service not found');
}
// receiveCharacteristic = await service.getCharacteristic(receiveCharUuid);
// if (!receiveCharacteristic) {
// return NotificationManager.error('Whoops, failed. Retry: Receive characteristic not found.');
// }
sendCharacteristic = await service.getCharacteristic(sendCharUuid);
if (!sendCharacteristic) {
return NotificationManager.error('Whoops, failed. Retry: Send characteristic not found.');
}
receiveCharacteristic = sendCharacteristic;
document.getElementById('connected').innerHTML = 'connected';
document.getElementById('connected').style.backgroundColor = 'green';
NotificationManager.success('Success to pair Bluetooth Device');
}
const listen = async () => {
if (receiveCharacteristic) {
receiveCharacteristic
.addEventListener('characteristicvaluechanged',
(evt) => {
const value = evt.target.value.getInt16(0, true);
document.getElementById('receiveValue').value = value;
});
receiveCharacteristic.startNotifications();
}
}
const disconnect = () => {
bluetoothDevice = null;
receiveCharacteristic = null;
sendCharacteristic = null;
document.getElementById('connected').innerHTML = 'disconnected';
document.getElementById('connected').style.backgroundColor = '';
}
const onClickDisconnect = () => {
if (!bluetoothDevice) {
return NotificationManager.warning('No device connected.');
}
if (bluetoothDevice.gatt.connected) {
bluetoothDevice.gatt.disconnect();
disconnect();
NotificationManager.success('Disconnected.');
} else {
NotificationManager.warning('Alredy disconnected');
}
}
const onClickSend = async () => {
if(!bluetoothDevice) return NotificationManager.warning('No device connected.');
const sendText = document.getElementById('sendText').value;
if (!sendText) return NotificationManager.error('Please fill send field.');
var _sendText = String(sendText);
// console.log(_sendText, new TextEncoder().encode(_sendText));
if (sendCharacteristic) sendCharacteristic.writeValue(new TextEncoder().encode(_sendText));
else NotificationManager.error('Whoops, sorry , retry : send:send');
}
const onClickReceive = () => {
if(!bluetoothDevice) return NotificationManager.warning('No device connected.');
return listen();
}
return (
<div className="App">
<Container>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Service UUID: </span>
</Col>
<Col xs={8} md={6} lg={4} className="d-flex align-items-center">
<input placeholder="ex: 0xFFE0" type="text" id="serviceUuid" className="col-10 rounded"></input>
</Col>
</Row>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Send UUID: </span>
</Col>
<Col xs={8} md={6} lg={4} className="d-flex align-items-center">
<input placeholder="ex: 0xFFE1" type="text" id="sendUuid" className="col-10 rounded"></input>
</Col>
</Row>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Recieve UUID: </span>
</Col>
<Col xs={8} md={6} lg={4} className="d-flex align-items-center">
<input placeholder="ex: 0xFFE2" type="text" id="receiveUuid" className="col-10 rounded"></input>
</Col>
</Row>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Send : </span>
</Col>
<Col xs={8} md={6} lg={4} className="d-flex align-items-center">
<input placeholder="Type here..." type="text" id="sendText" className="col-10 rounded"></input>
</Col>
</Row>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Receive : </span>
</Col>
<Col xs={8} md={6} lg={4} className="d-flex align-items-center">
<input placeholder="Receive text will be displayed here." id="receiveValue" className="col-10 bg-white rounded" disabled></input>
</Col>
</Row>
<Row className="d-flex justify-content-around my-2">
<Col xs={4} md={3} lg={2} className="text-right">
<span className="text-white">Status :</span>
</Col>
<Col xs={8} md={6} lg={4}>
<div id="connected" className="col-10 text-white text-center border rounded-lg px-2">
disconnected
</div>
</Col>
</Row>
<Row className="d-flex justify-content-around">
<Col xs={6} md={3} lg={2} className="text-center my-3">
<Button className="w-75" color="primary" onClick={onClickConnect} disabled={!isEnabled}>Connect</Button>
</Col>
<Col xs={6} md={3} lg={2} className="text-center my-3">
<Button className="w-75" color="success" onClick={onClickReceive} disabled={!isEnabled}>Recieve</Button>
</Col>
<Col xs={6} md={3} lg={2} className="text-center my-3">
<Button className="w-75" color="info" onClick={onClickSend} disabled={!isEnabled}>Send</Button>
</Col>
<Col xs={6} md={3} lg={2} className="text-center my-3">
<Button className="w-75" color="danger" onClick={onClickDisconnect} disabled={!isEnabled}>Disconnect</Button>
</Col>
</Row>
<NotificationContainer />
</Container>
</div >
);
};
export default App;
Anybody knows solution?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
