Git Product home page Git Product logo

Comments (13)

varun761 avatar varun761 commented on September 25, 2024

Code

import {
  View,
  Text,
  TouchableOpacity,
  Platform,
  FlatList,
  Dimensions,
  NativeEventEmitter,
  NativeModules,
  SafeAreaView,
} from "react-native";
import {
  PERMISSIONS,
  RESULTS,
  checkMultiple,
  requestMultiple,
} from "react-native-permissions";
import React, {useState, useEffect, useCallback} from "react";
import BleManager from "react-native-ble-manager";
import {shallowEqual, useDispatch, useSelector} from "react-redux";
import {Buffer} from "buffer";

import styles from "./style";
import TopBar from "../../components/TopBar";
import { addTempData, addUpdateItem, selectorConnectedDevices, selectorDeviceConnected, updateScanningStatus, updateSensorData, updatedBluetoothStatus } from "../../redux/slices/deviceSlice";
import SectionHeading from "../../components/SectionHeading";
import { useFocusEffect } from "@react-navigation/native";

const {height} = Dimensions.get("window");
const navHeight = Platform.OS === "android" ? 55 : 85;
const screenArea = height - navHeight;

const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);

const serviceUUIDList = ["8de5e532-7565-4c8b-b333-5866350be21f"];

const ListBluetoothDevices = () => {

  const dispatch = useDispatch()
  
  const deviceState = useSelector(state => state.device);

  const discoveredDevices = selectorConnectedDevices(deviceState);
  const isDeviceConnected = selectorDeviceConnected(deviceState);

  // console.log('---isDeviceConnected---- :', isDeviceConnected)

  const isScanning = useSelector(
    state => state.device.scanningDevices === true,
  );

  const checkDeviceBlePermissions = async () => {
    return new Promise(async (resolve, reject) => {
      console.log("checking permissions");
      try {
        if (Platform.OS === "android") {
          const permissionsList = [
            PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
            PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE,
            PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
          ];
          const permissions = await checkMultiple(permissionsList);
          const requestPermission = Object.keys(permissions).filter(
            el =>
              permissions[el] !== RESULTS.UNAVAILABLE &&
              permissions[el] !== RESULTS.GRANTED &&
              permissions[el] !== RESULTS.LIMITED,
          );
          if (requestPermission.length > 0) {
            const requestPermissionsResponse = await requestMultiple(
              requestPermission,
            );
            const requestPermissionRejected = Object.keys(
              requestPermissionsResponse,
            ).filter(el => requestPermissionsResponse[el] !== RESULTS.GRANTED);
            if (requestPermissionRejected.length > 0) {
              const errorMessage = `Please go to application settings and allow all required permission. Please share below information with developer. Version: ${Platform.Version}, OS: ${Platform.OS}, Release: ${Platform.constants.Release}`
              alert(errorMessage);
              reject(errorMessage)
            }
          }
          resolve(true)
        } else {
          const permissions = await checkMultiple([PERMISSIONS.IOS.BLUETOOTH]);
          const requestPermission = Object.keys(permissions).filter(
            el =>
              permissions[el] !== RESULTS.UNAVAILABLE &&
              permissions[el] !== RESULTS.GRANTED &&
              permissions[el] !== RESULTS.LIMITED,
          );
          if (requestPermission.length > 0) {
            const requestPermissionsResponse = await requestMultiple(
              requestPermission,
            );
            const requestPermissionRejected = Object.keys(
              requestPermissionsResponse,
            ).filter(el => requestPermissionsResponse[el] !== RESULTS.GRANTED);
            if (requestPermissionRejected.length > 0) {
              const errorMessage = `Please allow bluetooth and location permission. Please share below information with developer. Platform: IOS, Version: OS: ${
                Platform.OS
              }, Version: ${Platform.constants.osVersion}, System ${
                Platform.constants.systemName
              }, ${JSON.stringify(requestPermissionRejected)}`
              alert(errorMessage);
              reject(errorMessage)
            }
          }
          resolve(true)
        }
      } catch(e) {
        console.log('Permission issue. ', e)
        reject(e)
      }
    })
  }

  useEffect(() => {
    BleManager.start({
      showAlert: false,
    }).then(async () => {
      console.log('ble working well')
      try {
        const permissionEnabled = await checkDeviceBlePermissions()
        if (permissionEnabled) {
          const bluetoothEnabled = await isDeviceBluetoothWorking()
          if (!bluetoothEnabled) {
            if (Platform.OS === 'android') {
              enableAndroidBluetooth()
              .then(() => {
                dispatch(updatedBluetoothStatus(true));
              }).catch((e) => {
                console.log('enable bluetooth issue. ', e)
                dispatch(updatedBluetoothStatus(false));
              })
            } else {
              // alert('Please enable bluetooth.')
              dispatch(updatedBluetoothStatus(true));
              return false
            }
          }
        }
      } catch(e) {
        console.log('issue ---- ', e)
      }
    }).catch((e) => {
      console.log('ble manager issue', e)
    })
  }, [])

  const identifyReceivingData = data => {
    try {
      let type = "no_data";
      const first_bit = data && data.length > 0 ? data[0]: null;

      if (data.length === 2 && first_bit === 1 && data[1] === 1) {
        type = "heartbeat";
      } else if (data.length === 2 && first_bit === 34 && data[1] === 34) {
        type = "stop_collect_sensor_data";
      } else if (data.length === 2 && first_bit === 17 && data[1] === 17) {
        type = "start_collect_sensor_data";
      } else if (data.length === 3 && first_bit === 0) {
        type = "sensor_data_information";
      } else if (data.length === 3 && first_bit === 1) {
        type = "date_time_data_information";
      } else if (data.length === 3 && first_bit === 2) {
        type = "battery_data_information";
      } else if (data.length === 8) {
        type = "time_information";
      } else if (data.length > 8) {
        type = "sensor_data";
      }
      return type;
    } catch(e) {
      console.log('----issue----- ', e)
      return 'no_data'
    }
  };

  useEffect(() => {
    console.log('--- added listeners----')
    let stopUpdateBleListeners = bleManagerEmitter.addListener(
      "BleManagerDidUpdateState",
      args => {
        console.log("BleManagerDidUpdateState : ", args);
      },
    );

    let stopDiscoverListener = bleManagerEmitter.addListener(
      "BleManagerDiscoverPeripheral",
      peripheral => {
        if (Object.keys(peripheral).indexOf('name') > -1 && Object.keys(peripheral).indexOf('advertising') > -1 && peripheral.name) {
          const currentDate = new Date()
          dispatch(addUpdateItem({...peripheral, lastActivityTime: currentDate.getTime()}))
        }
      },
    )

    let stopConnectListener = bleManagerEmitter.addListener(
      "BleManagerConnectPeripheral",
      peripheral => {
        console.log(
          "BleManagerConnectPeripheral:",
          JSON.stringify(peripheral),
        );
      },
    )

    let stopScanListener = bleManagerEmitter.addListener(
      "BleManagerStopScan",
      () => {
        dispatch(updateScanningStatus(false));
        console.log("scan stopped");
      },
    );

    let stopDisconnectListener = bleManagerEmitter.addListener(
      "BleManagerDisconnectPeripheral",
      (event) => {
        console.debug(
          `[handleDisconnectedPeripheral][${event.peripheral}] disconnected.`,
        );
      }
    );

    let receiveDataListener = bleManagerEmitter.addListener(
      "BleManagerDidUpdateValueForCharacteristic",
      (args) => {
        // {value, peripheral, characteristic, service}
        try {
          // let rawData = [...value];
          // let typeOfData = identifyReceivingData(rawData);
          console.log("---START DEBUGGER--- :");
          // console.log({value, peripheral, characteristic, service});
          console.log(args);
          console.log("---END DEBUGGER--- : ");

          // heartbeat : For connection
          // if (typeOfData === "heartbeat") {
          //   // const timeStamp = new Date();
          //   // dispatch(
          //   //   updateConnectionState({
          //   //     deviceId: peripheral,
          //   //     lastUpdatedTime: timeStamp.getTime(),
          //   //   }),
          //   // );
          //   // send 0x01
          //   // setTimeout(() => {
          //   //   try {
          //   //     sendCommandToDevice(
          //   //       peripheral,
          //   //       singleServiceUID,
          //   //       writeCharacteristicUUID,
          //   //       "0x01, 0x01",
          //   //     );
          //   //   } catch (e) {
          //   //     console.log("====sendCommandToDevice issue=== :", e);
          //   //   }
          //   // }, 1000);
          // } else if (typeOfData === "sensor_data_information") {
          //   rawData.splice(0, 1);
          //   const total_data_length =
          //     parseFloat(parseFloat(rawData[0]) * 256) +
          //     parseFloat(rawData[1]);
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_total_count: parseFloat(total_data_length / 12),
          //     }),
          //   );
          // } else if (typeOfData === "date_time_data_information") {
          //   rawData.splice(0, 1);
          //   const total_data_length =
          //     parseFloat(parseFloat(rawData[0]) * 256) +
          //     parseFloat(rawData[1]);
          //   console.log("date_time_data_information", total_data_length);
          // } else if (typeOfData === "battery_data_information") {
          //   console.log("battery_data_information");
          // } else if (typeOfData === "time_information") {
          //   const monthValue =
          //     parseFloat(value[1]) < 10 ? `0${value[1]}` : value[1];
          //   const dateValue =
          //     parseFloat(value[2]) < 10 ? `0${value[2]}` : value[2];
          //   const miliSecond = parseFloat(`${value[6]}${value[7]}`);
          //   const information = `20${value[0]}-${monthValue}-${dateValue} ${value[3]}:${value[4]}:${value[5]}`;
          //   const date_time = new Date(information);
          //   date_time.setMilliseconds(miliSecond);
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_date: date_time
          //         .toISOString()
          //         .replace(/:/g, "")
          //         .replace(".", "+")
          //         .replace("Z", ""),
          //     }),
          //   );
          //   console.log(`${typeOfData} - ${date_time.toISOString()}`);
          // } else if (typeOfData === "sensor_data") {
          //   console.log('----sensor data -----')
          //   const allSensorData = [];
          //   for (let j = 0; j < rawData.length; j += 12) {
          //     const singleDataBuffer = rawData.slice(j, j + 12);
          //     const sensorData = {
          //       x_accel: 0,
          //       y_accel: 0,
          //       z_accel: 0,
          //       x_gyro: 0,
          //       y_gyro: 0,
          //       z_gyro: 0,
          //     };
          //     const parsedValues = [];
          //     for (let i = 0; i < singleDataBuffer.length; i += 2) {
          //       const parsingValue = singleDataBuffer.slice(i, i + 2);
          //       const sensorValue = parseFloat(parsingValue[1]);
          //       const signedValue = parseFloat(parsingValue[0]);
          //       let multipleFactor = 2000;
          //       if (i > 4) {
          //         multipleFactor = 20000;
          //       }
          //       const calculatedValue = Number(
          //         (
          //           (parseFloat(signedValue * 256) +
          //             parseFloat(sensorValue - multipleFactor)) /
          //           10
          //         ).toPrecision(3),
          //       );
          //       parsedValues.push(
          //         !isNaN(calculatedValue) ? calculatedValue : 0,
          //       );
          //     }

          //     const propertiesKeys = Object.keys(sensorData);
          //     for (let i = 0; i < propertiesKeys.length; i++) {
          //       sensorData[propertiesKeys[i]] =
          //         typeof parsedValues[i] != "undefined" ? parsedValues[i] : 0;
          //     }

          //     allSensorData.push(sensorData);
          //   }

          //   console.log("----data saving----- : ");
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_data: allSensorData,
          //     }),
          //   );
          // } else if (typeOfData === "start_collect_sensor_data") {
          //   console.log("---start_collect_sensor_data----");
          // } else if (typeOfData === "stop_collect_sensor_data") {
          //   console.log("End Notification : ");
          //   console.log("writing now ------ :: ");
          //   dispatch(
          //     updateSensorData({
          //       deviceId: peripheral,
          //     }),
          //   );
          //   BleManager.disconnect(peripheral)
          //   .then(() => {
          //     console.log('----successfully disconnected-----')
          //   })
          //   .catch((e) => {
          //     console.log('--subscriber event issue--- disconnect--- :', e)
          //   })
          // }
        } catch(e) {
          console.log("---ISSUE WITH DATA PARSING---");
          console.log(e);
          console.log("---ISSUE WITH DATA PARSING---");
        }
        return true
      },
    )
    return () => {
      console.log('------unsubscribe-----')
      stopDiscoverListener.remove();
      stopConnectListener.remove();
      stopScanListener.remove();
      receiveDataListener.remove();
      stopUpdateBleListeners.remove();
      stopDisconnectListener.remove();
    };
  }, [])

  useFocusEffect(useCallback(() => {
    const initialCheckup = async () => {
      try {
        const permissionEnabled = await checkDeviceBlePermissions()
        if (permissionEnabled) {
          const bluetoothEnabled = await isDeviceBluetoothWorking()
          if (!bluetoothEnabled) {
            if (Platform.OS === 'android') {
              enableAndroidBluetooth()
              .then(() => {
                dispatch(updatedBluetoothStatus(true));
              }).catch((e) => {
                console.log('enable bluetooth issue. ', e)
                dispatch(updatedBluetoothStatus(false));
              })
            } else {
              alert('Please enable bluetooth.')
              dispatch(updatedBluetoothStatus(true));
              return false
            }
          }
        }
      } catch(e) {
        console.log('issue ---- ', e)
      }
    }
    initialCheckup();
  }, []))

  const enableAndroidBluetooth = () => {
    return new Promise(async (resolve, reject) => {
      try {
        await BleManager.enableBluetooth();
        resolve(true)
      } catch(e) {
        reject(e)
      }
    })
  }

  const isDeviceBluetoothWorking = () => {
    return BleManager.checkState()
      .then((state) => {
        console.log('device bluetooth state : ', state)
        if (state === 'on') {
          return true;
        }
        return false
      })
      .catch((e) => {
        console.log('device bluetooth state issue : ', e)
        return false;
      })
  }

  const toggleScan = async (scanningNow) => {
    // if scanning stop scanning
    console.log('ScanningStatus : ', scanningNow)
    try {
      const bluetoothEnabled = await isDeviceBluetoothWorking()
      if (!bluetoothEnabled) {
        alert('Please enable bluetooth and try again')
        if (scanningNow) {
          dispatch(updateScanningStatus(false));
        }
        return false
      }
      // check if scanning now
      if (!scanningNow) {
        try {
          await BleManager.scan(serviceUUIDList, -1, true)
          dispatch(updateScanningStatus(true));
        } catch(scanningError) {
          console.log('Issue in scanning. ', scanningError)
          dispatch(updateScanningStatus(false));
        }
      } else {
        try {
          await BleManager.stopScan();
        } catch(stopScanningError) {
          console.log('Issue in stop scanning. ', stopScanningError)
        }
      }
    } catch(e) {
      console.log('---scanning issue----', e)
    }
  }

  const RenderBleDeviceLists = ({peripheral}) => {
    const {name, id } = peripheral;
    return (
      <>
        {name && (
          <View style={styles.bleListMainView}>
            <View style={{flex: 1}}>
              <Text style={styles.bleListNameText}>{name}</Text>
              <Text style={styles.bleListIdText}>ID: {id}</Text>
            </View>
          </View>
        )}
      </>
    );
  };

  return (
    <View style={styles.mainView}>
      <TopBar deviceConnected={isDeviceConnected} />
      <View style={styles.contentView}>
        <View style={styles.headingTextContainer}>
          <Text style={styles.headingText}>Devices</Text>
        </View>
        <TouchableOpacity
          onPress={() => toggleScan(isScanning)}
          style={styles.scanButton}>
          <Text style={styles.scanButtonText}>
            {isScanning ? "Stop Scanning" : "Scan Devices"}
          </Text>
        </TouchableOpacity>
        <View style={{marginTop: 20}}>
          <SectionHeading
            title="All Devices"
            countTitle="discovered"
            count={discoveredDevices ? discoveredDevices.length : 0}
          />
          {discoveredDevices && discoveredDevices.length > 0 ? (
            <SafeAreaView>
              <FlatList
                style={{maxHeight: screenArea * 0.27}}
                data={discoveredDevices}
                renderItem={({item}) => (
                  <RenderBleDeviceLists
                    peripheral={item}
                  />
                )}
                keyExtractor={item => `${item.id}_discovered`}
              />
            </SafeAreaView>
          ) : (
            <Text style={{color: "#000", paddingHorizontal: 2}}>
              {isScanning
                ? "Scanning for devices ... "
                : "No Device Discovered"}
            </Text>
          )}
        </View>
      </View>
    </View>
  )
}

export default ListBluetoothDevices

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

After requestMTU the data was received. But it suppose to receive data without requestMTU.

from react-native-ble-manager.

marcosinigaglia avatar marcosinigaglia commented on September 25, 2024

Is not a bug, is how BLE is designed in the OS

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

Every time we need to call requestMTU while receive data? @marcosinigaglia

from react-native-ble-manager.

marcosinigaglia avatar marcosinigaglia commented on September 25, 2024

The default MTU on Android is 20, so after connecting it should be set to the size you need.

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

And what is the maximum MTU we can set? I set it to 1000 and it never return any thing.

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

@marcosinigaglia I am receiving 160 values in one transmission. It will transmit 2560 values total. Then what to set MTU and what will be approach ?

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

@marcosinigaglia I hope this information will help

06-06 00:40:03.941 941 22637 D r_submix: read_frames 21813390336, T_rec 454445.656250s, p_vs_o 15209us 06-06 00:40:04.004 942 965 D [email protected]: BtHostDebugInfo 06-06 00:40:04.004 942 965 D [BT] : mtk_bt_op: BT_VND_OP_SET_BTHOST 06-06 00:40:04.008 2096 2555 I bt_stack: [INFO:btsnoop.cc(342)] clear_l2cap_allowlist: Clearing acceptlist from l2cap channel. conn_handle=512 cid=4:4 06-06 00:40:04.009 2096 2555 I bt_stack: [INFO:gatt_attr.cc(338)] gatt_connect_cback: remove untrusted client status, bda=e7:01:a9:03:d3:8c 06-06 00:40:04.009 2096 2555 I bluetooth: system/bt/stack/gap/gap_ble.cc:298 client_connect_cback: No active GAP service found for peer:xx:xx:xx:xx:d3:8c callback:Disconnected 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:3 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:4 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:5 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:6 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:7 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.011 2096 2555 I bt_bta_gattc: system/bt/bta/gatt/bta_gattc_act.cc:1148 bta_gattc_conn_cback: Disconnected att_id:8 transport:le reason:GATT_CONN_TIMEOUT 06-06 00:40:04.012 2096 2555 W bt_btm_sec: system/bt/stack/btm/btm_sec.cc:3849 btm_sec_disconnected: Got uncommon disconnection reason:Connection Timeout handle:0x0200 06-06 00:40:04.012 2096 2555 I btif_av : system/bt/btif/src/btif_av.cc:4184 btif_av_get_peer_sep: No active sink or source peer found 06-06 00:40:04.012 2096 2555 I bt_btif_a2dp_source: system/bt/btif/src/btif_a2dp_source.cc:850 btif_a2dp_source_on_idle: btif_a2dp_source_on_idle: state=STATE_OFF 06-06 00:40:04.012 2096 2555 I btif_av : system/bt/btif/src/btif_av.cc:4184 btif_av_get_peer_sep: No active sink or source peer found 06-06 00:40:04.012 2096 2555 I bt_btif_a2dp_source: system/bt/btif/src/btif_a2dp_source.cc:850 btif_a2dp_source_on_idle: btif_a2dp_source_on_idle: state=STATE_OFF 06-06 00:40:04.012 942 965 D [email protected]: BtHostDebugInfo 06-06 00:40:04.012 942 965 D [BT] : mtk_bt_op: BT_VND_OP_SET_BTHOST 06-06 00:40:04.015 2096 31976 D BluetoothMetrics: btclass1f00 06-06 00:40:04.015 27885 27925 D BluetoothGatt: onClientConnectionState() - status=0 clientIf=8 device=E7:01:A9:03:D3:8C 06-06 00:40:04.016 942 965 D [email protected]: BtHostDebugInfo 06-06 00:40:04.016 942 965 D [BT] : mtk_bt_op: BT_VND_OP_SET_BTHOST 06-06 00:40:04.016 27885 27925 D RNBleManager: onConnectionStateChange to 0 on peripheral: E7:01:A9:03:D3:8C with status 0 06-06 00:40:04.018 2096 31976 D Checkin : publish the event [tag = MOT_BT event name = DISC] 06-06 00:40:04.020 27885 27885 D BluetoothGatt: cancelOpen() - device: E7:01:A9:03:D3:8C 06-06 00:40:04.024 27885 27885 D BluetoothGatt: close() 06-06 00:40:04.024 27885 27885 D BluetoothGatt: unregisterApp() - mClientIf=8 06-06 00:40:04.034 27885 27885 D RNBleManager: Peripheral event (BleManagerDisconnectPeripheral):E7:01:A9:03:D3:8C 06-06 00:40:04.035 2128 2223 W BluetoothEventManager: AclStateChangedHandler: activeDevice is null

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

The device disconnects on BLE_GATT_STATUS_SUCCESS 0x0000. code

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v3.0.0%2Fgroup___b_l_e___g_a_t_t___s_t_a_t_u_s___c_o_d_e_s.html

from react-native-ble-manager.

itsaliraxa avatar itsaliraxa commented on September 25, 2024

Code

import {
  View,
  Text,
  TouchableOpacity,
  Platform,
  FlatList,
  Dimensions,
  NativeEventEmitter,
  NativeModules,
  SafeAreaView,
} from "react-native";
import {
  PERMISSIONS,
  RESULTS,
  checkMultiple,
  requestMultiple,
} from "react-native-permissions";
import React, {useState, useEffect, useCallback} from "react";
import BleManager from "react-native-ble-manager";
import {shallowEqual, useDispatch, useSelector} from "react-redux";
import {Buffer} from "buffer";

import styles from "./style";
import TopBar from "../../components/TopBar";
import { addTempData, addUpdateItem, selectorConnectedDevices, selectorDeviceConnected, updateScanningStatus, updateSensorData, updatedBluetoothStatus } from "../../redux/slices/deviceSlice";
import SectionHeading from "../../components/SectionHeading";
import { useFocusEffect } from "@react-navigation/native";

const {height} = Dimensions.get("window");
const navHeight = Platform.OS === "android" ? 55 : 85;
const screenArea = height - navHeight;

const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);

const serviceUUIDList = ["8de5e532-7565-4c8b-b333-5866350be21f"];

const ListBluetoothDevices = () => {

  const dispatch = useDispatch()
  
  const deviceState = useSelector(state => state.device);

  const discoveredDevices = selectorConnectedDevices(deviceState);
  const isDeviceConnected = selectorDeviceConnected(deviceState);

  // console.log('---isDeviceConnected---- :', isDeviceConnected)

  const isScanning = useSelector(
    state => state.device.scanningDevices === true,
  );

  const checkDeviceBlePermissions = async () => {
    return new Promise(async (resolve, reject) => {
      console.log("checking permissions");
      try {
        if (Platform.OS === "android") {
          const permissionsList = [
            PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
            PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE,
            PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
          ];
          const permissions = await checkMultiple(permissionsList);
          const requestPermission = Object.keys(permissions).filter(
            el =>
              permissions[el] !== RESULTS.UNAVAILABLE &&
              permissions[el] !== RESULTS.GRANTED &&
              permissions[el] !== RESULTS.LIMITED,
          );
          if (requestPermission.length > 0) {
            const requestPermissionsResponse = await requestMultiple(
              requestPermission,
            );
            const requestPermissionRejected = Object.keys(
              requestPermissionsResponse,
            ).filter(el => requestPermissionsResponse[el] !== RESULTS.GRANTED);
            if (requestPermissionRejected.length > 0) {
              const errorMessage = `Please go to application settings and allow all required permission. Please share below information with developer. Version: ${Platform.Version}, OS: ${Platform.OS}, Release: ${Platform.constants.Release}`
              alert(errorMessage);
              reject(errorMessage)
            }
          }
          resolve(true)
        } else {
          const permissions = await checkMultiple([PERMISSIONS.IOS.BLUETOOTH]);
          const requestPermission = Object.keys(permissions).filter(
            el =>
              permissions[el] !== RESULTS.UNAVAILABLE &&
              permissions[el] !== RESULTS.GRANTED &&
              permissions[el] !== RESULTS.LIMITED,
          );
          if (requestPermission.length > 0) {
            const requestPermissionsResponse = await requestMultiple(
              requestPermission,
            );
            const requestPermissionRejected = Object.keys(
              requestPermissionsResponse,
            ).filter(el => requestPermissionsResponse[el] !== RESULTS.GRANTED);
            if (requestPermissionRejected.length > 0) {
              const errorMessage = `Please allow bluetooth and location permission. Please share below information with developer. Platform: IOS, Version: OS: ${
                Platform.OS
              }, Version: ${Platform.constants.osVersion}, System ${
                Platform.constants.systemName
              }, ${JSON.stringify(requestPermissionRejected)}`
              alert(errorMessage);
              reject(errorMessage)
            }
          }
          resolve(true)
        }
      } catch(e) {
        console.log('Permission issue. ', e)
        reject(e)
      }
    })
  }

  useEffect(() => {
    BleManager.start({
      showAlert: false,
    }).then(async () => {
      console.log('ble working well')
      try {
        const permissionEnabled = await checkDeviceBlePermissions()
        if (permissionEnabled) {
          const bluetoothEnabled = await isDeviceBluetoothWorking()
          if (!bluetoothEnabled) {
            if (Platform.OS === 'android') {
              enableAndroidBluetooth()
              .then(() => {
                dispatch(updatedBluetoothStatus(true));
              }).catch((e) => {
                console.log('enable bluetooth issue. ', e)
                dispatch(updatedBluetoothStatus(false));
              })
            } else {
              // alert('Please enable bluetooth.')
              dispatch(updatedBluetoothStatus(true));
              return false
            }
          }
        }
      } catch(e) {
        console.log('issue ---- ', e)
      }
    }).catch((e) => {
      console.log('ble manager issue', e)
    })
  }, [])

  const identifyReceivingData = data => {
    try {
      let type = "no_data";
      const first_bit = data && data.length > 0 ? data[0]: null;

      if (data.length === 2 && first_bit === 1 && data[1] === 1) {
        type = "heartbeat";
      } else if (data.length === 2 && first_bit === 34 && data[1] === 34) {
        type = "stop_collect_sensor_data";
      } else if (data.length === 2 && first_bit === 17 && data[1] === 17) {
        type = "start_collect_sensor_data";
      } else if (data.length === 3 && first_bit === 0) {
        type = "sensor_data_information";
      } else if (data.length === 3 && first_bit === 1) {
        type = "date_time_data_information";
      } else if (data.length === 3 && first_bit === 2) {
        type = "battery_data_information";
      } else if (data.length === 8) {
        type = "time_information";
      } else if (data.length > 8) {
        type = "sensor_data";
      }
      return type;
    } catch(e) {
      console.log('----issue----- ', e)
      return 'no_data'
    }
  };

  useEffect(() => {
    console.log('--- added listeners----')
    let stopUpdateBleListeners = bleManagerEmitter.addListener(
      "BleManagerDidUpdateState",
      args => {
        console.log("BleManagerDidUpdateState : ", args);
      },
    );

    let stopDiscoverListener = bleManagerEmitter.addListener(
      "BleManagerDiscoverPeripheral",
      peripheral => {
        if (Object.keys(peripheral).indexOf('name') > -1 && Object.keys(peripheral).indexOf('advertising') > -1 && peripheral.name) {
          const currentDate = new Date()
          dispatch(addUpdateItem({...peripheral, lastActivityTime: currentDate.getTime()}))
        }
      },
    )

    let stopConnectListener = bleManagerEmitter.addListener(
      "BleManagerConnectPeripheral",
      peripheral => {
        console.log(
          "BleManagerConnectPeripheral:",
          JSON.stringify(peripheral),
        );
      },
    )

    let stopScanListener = bleManagerEmitter.addListener(
      "BleManagerStopScan",
      () => {
        dispatch(updateScanningStatus(false));
        console.log("scan stopped");
      },
    );

    let stopDisconnectListener = bleManagerEmitter.addListener(
      "BleManagerDisconnectPeripheral",
      (event) => {
        console.debug(
          `[handleDisconnectedPeripheral][${event.peripheral}] disconnected.`,
        );
      }
    );

    let receiveDataListener = bleManagerEmitter.addListener(
      "BleManagerDidUpdateValueForCharacteristic",
      (args) => {
        // {value, peripheral, characteristic, service}
        try {
          // let rawData = [...value];
          // let typeOfData = identifyReceivingData(rawData);
          console.log("---START DEBUGGER--- :");
          // console.log({value, peripheral, characteristic, service});
          console.log(args);
          console.log("---END DEBUGGER--- : ");

          // heartbeat : For connection
          // if (typeOfData === "heartbeat") {
          //   // const timeStamp = new Date();
          //   // dispatch(
          //   //   updateConnectionState({
          //   //     deviceId: peripheral,
          //   //     lastUpdatedTime: timeStamp.getTime(),
          //   //   }),
          //   // );
          //   // send 0x01
          //   // setTimeout(() => {
          //   //   try {
          //   //     sendCommandToDevice(
          //   //       peripheral,
          //   //       singleServiceUID,
          //   //       writeCharacteristicUUID,
          //   //       "0x01, 0x01",
          //   //     );
          //   //   } catch (e) {
          //   //     console.log("====sendCommandToDevice issue=== :", e);
          //   //   }
          //   // }, 1000);
          // } else if (typeOfData === "sensor_data_information") {
          //   rawData.splice(0, 1);
          //   const total_data_length =
          //     parseFloat(parseFloat(rawData[0]) * 256) +
          //     parseFloat(rawData[1]);
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_total_count: parseFloat(total_data_length / 12),
          //     }),
          //   );
          // } else if (typeOfData === "date_time_data_information") {
          //   rawData.splice(0, 1);
          //   const total_data_length =
          //     parseFloat(parseFloat(rawData[0]) * 256) +
          //     parseFloat(rawData[1]);
          //   console.log("date_time_data_information", total_data_length);
          // } else if (typeOfData === "battery_data_information") {
          //   console.log("battery_data_information");
          // } else if (typeOfData === "time_information") {
          //   const monthValue =
          //     parseFloat(value[1]) < 10 ? `0${value[1]}` : value[1];
          //   const dateValue =
          //     parseFloat(value[2]) < 10 ? `0${value[2]}` : value[2];
          //   const miliSecond = parseFloat(`${value[6]}${value[7]}`);
          //   const information = `20${value[0]}-${monthValue}-${dateValue} ${value[3]}:${value[4]}:${value[5]}`;
          //   const date_time = new Date(information);
          //   date_time.setMilliseconds(miliSecond);
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_date: date_time
          //         .toISOString()
          //         .replace(/:/g, "")
          //         .replace(".", "+")
          //         .replace("Z", ""),
          //     }),
          //   );
          //   console.log(`${typeOfData} - ${date_time.toISOString()}`);
          // } else if (typeOfData === "sensor_data") {
          //   console.log('----sensor data -----')
          //   const allSensorData = [];
          //   for (let j = 0; j < rawData.length; j += 12) {
          //     const singleDataBuffer = rawData.slice(j, j + 12);
          //     const sensorData = {
          //       x_accel: 0,
          //       y_accel: 0,
          //       z_accel: 0,
          //       x_gyro: 0,
          //       y_gyro: 0,
          //       z_gyro: 0,
          //     };
          //     const parsedValues = [];
          //     for (let i = 0; i < singleDataBuffer.length; i += 2) {
          //       const parsingValue = singleDataBuffer.slice(i, i + 2);
          //       const sensorValue = parseFloat(parsingValue[1]);
          //       const signedValue = parseFloat(parsingValue[0]);
          //       let multipleFactor = 2000;
          //       if (i > 4) {
          //         multipleFactor = 20000;
          //       }
          //       const calculatedValue = Number(
          //         (
          //           (parseFloat(signedValue * 256) +
          //             parseFloat(sensorValue - multipleFactor)) /
          //           10
          //         ).toPrecision(3),
          //       );
          //       parsedValues.push(
          //         !isNaN(calculatedValue) ? calculatedValue : 0,
          //       );
          //     }

          //     const propertiesKeys = Object.keys(sensorData);
          //     for (let i = 0; i < propertiesKeys.length; i++) {
          //       sensorData[propertiesKeys[i]] =
          //         typeof parsedValues[i] != "undefined" ? parsedValues[i] : 0;
          //     }

          //     allSensorData.push(sensorData);
          //   }

          //   console.log("----data saving----- : ");
          //   dispatch(
          //     addTempData({
          //       deviceId: peripheral,
          //       impact_data: allSensorData,
          //     }),
          //   );
          // } else if (typeOfData === "start_collect_sensor_data") {
          //   console.log("---start_collect_sensor_data----");
          // } else if (typeOfData === "stop_collect_sensor_data") {
          //   console.log("End Notification : ");
          //   console.log("writing now ------ :: ");
          //   dispatch(
          //     updateSensorData({
          //       deviceId: peripheral,
          //     }),
          //   );
          //   BleManager.disconnect(peripheral)
          //   .then(() => {
          //     console.log('----successfully disconnected-----')
          //   })
          //   .catch((e) => {
          //     console.log('--subscriber event issue--- disconnect--- :', e)
          //   })
          // }
        } catch(e) {
          console.log("---ISSUE WITH DATA PARSING---");
          console.log(e);
          console.log("---ISSUE WITH DATA PARSING---");
        }
        return true
      },
    )
    return () => {
      console.log('------unsubscribe-----')
      stopDiscoverListener.remove();
      stopConnectListener.remove();
      stopScanListener.remove();
      receiveDataListener.remove();
      stopUpdateBleListeners.remove();
      stopDisconnectListener.remove();
    };
  }, [])

  useFocusEffect(useCallback(() => {
    const initialCheckup = async () => {
      try {
        const permissionEnabled = await checkDeviceBlePermissions()
        if (permissionEnabled) {
          const bluetoothEnabled = await isDeviceBluetoothWorking()
          if (!bluetoothEnabled) {
            if (Platform.OS === 'android') {
              enableAndroidBluetooth()
              .then(() => {
                dispatch(updatedBluetoothStatus(true));
              }).catch((e) => {
                console.log('enable bluetooth issue. ', e)
                dispatch(updatedBluetoothStatus(false));
              })
            } else {
              alert('Please enable bluetooth.')
              dispatch(updatedBluetoothStatus(true));
              return false
            }
          }
        }
      } catch(e) {
        console.log('issue ---- ', e)
      }
    }
    initialCheckup();
  }, []))

  const enableAndroidBluetooth = () => {
    return new Promise(async (resolve, reject) => {
      try {
        await BleManager.enableBluetooth();
        resolve(true)
      } catch(e) {
        reject(e)
      }
    })
  }

  const isDeviceBluetoothWorking = () => {
    return BleManager.checkState()
      .then((state) => {
        console.log('device bluetooth state : ', state)
        if (state === 'on') {
          return true;
        }
        return false
      })
      .catch((e) => {
        console.log('device bluetooth state issue : ', e)
        return false;
      })
  }

  const toggleScan = async (scanningNow) => {
    // if scanning stop scanning
    console.log('ScanningStatus : ', scanningNow)
    try {
      const bluetoothEnabled = await isDeviceBluetoothWorking()
      if (!bluetoothEnabled) {
        alert('Please enable bluetooth and try again')
        if (scanningNow) {
          dispatch(updateScanningStatus(false));
        }
        return false
      }
      // check if scanning now
      if (!scanningNow) {
        try {
          await BleManager.scan(serviceUUIDList, -1, true)
          dispatch(updateScanningStatus(true));
        } catch(scanningError) {
          console.log('Issue in scanning. ', scanningError)
          dispatch(updateScanningStatus(false));
        }
      } else {
        try {
          await BleManager.stopScan();
        } catch(stopScanningError) {
          console.log('Issue in stop scanning. ', stopScanningError)
        }
      }
    } catch(e) {
      console.log('---scanning issue----', e)
    }
  }

  const RenderBleDeviceLists = ({peripheral}) => {
    const {name, id } = peripheral;
    return (
      <>
        {name && (
          <View style={styles.bleListMainView}>
            <View style={{flex: 1}}>
              <Text style={styles.bleListNameText}>{name}</Text>
              <Text style={styles.bleListIdText}>ID: {id}</Text>
            </View>
          </View>
        )}
      </>
    );
  };

  return (
    <View style={styles.mainView}>
      <TopBar deviceConnected={isDeviceConnected} />
      <View style={styles.contentView}>
        <View style={styles.headingTextContainer}>
          <Text style={styles.headingText}>Devices</Text>
        </View>
        <TouchableOpacity
          onPress={() => toggleScan(isScanning)}
          style={styles.scanButton}>
          <Text style={styles.scanButtonText}>
            {isScanning ? "Stop Scanning" : "Scan Devices"}
          </Text>
        </TouchableOpacity>
        <View style={{marginTop: 20}}>
          <SectionHeading
            title="All Devices"
            countTitle="discovered"
            count={discoveredDevices ? discoveredDevices.length : 0}
          />
          {discoveredDevices && discoveredDevices.length > 0 ? (
            <SafeAreaView>
              <FlatList
                style={{maxHeight: screenArea * 0.27}}
                data={discoveredDevices}
                renderItem={({item}) => (
                  <RenderBleDeviceLists
                    peripheral={item}
                  />
                )}
                keyExtractor={item => `${item.id}_discovered`}
              />
            </SafeAreaView>
          ) : (
            <Text style={{color: "#000", paddingHorizontal: 2}}>
              {isScanning
                ? "Scanning for devices ... "
                : "No Device Discovered"}
            </Text>
          )}
        </View>
      </View>
    </View>
  )
}

export default ListBluetoothDevices

HI @varun761 I am not able get the values from this listener
BleManagerDidUpdateValueForCharacteristic, can you please help me how I can get data?

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

@itsaliraxa Yes sure. Add me to skype live:sharma.varun76.

from react-native-ble-manager.

varun761 avatar varun761 commented on September 25, 2024

Increasing the data transmission time can help you out. If it's 5s right now make it 10 seconds or more. Processing of data depends upon the mobile device.

from react-native-ble-manager.

itsaliraxa avatar itsaliraxa commented on September 25, 2024

from react-native-ble-manager.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.