Skip to content

munimtechnologies/munim-bluetooth-peripheral

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

64 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Munim Technologies Bluetooth Peripheral

munim-bluetooth-peripheral

Package version License: MIT Downloads

Works with Expo  ‒  Read the Documentation  ‒  Report Issues

Follow Munim Technologies

Munim Technologies on GitHub Β  Munim Technologies on LinkedIn Β  Munim Technologies Website

Introduction

munim-bluetooth-peripheral is a React Native library for creating Bluetooth Low Energy (BLE) peripheral devices. This library allows your React Native app to act as a BLE peripheral, advertising services and characteristics that other devices can discover and connect to.

Fully compatible with Expo! Works seamlessly with both Expo managed and bare workflows.

Note: This library focuses on reliability and platform compatibility. It supports the core BLE advertising data types that work consistently across both Android and iOS platforms, rather than attempting to support all possible BLE features which may not work reliably.

Table of contents

πŸ“š Documentation

Learn about building BLE peripheral apps in our documentation!

πŸš€ Features

  • πŸ”΅ BLE Peripheral Mode: Transform your React Native app into a BLE peripheral device
  • πŸ“‘ Service Advertising: Advertise custom GATT services with multiple characteristics
  • πŸ”„ Real-time Communication: Support for read, write, and notify operations
  • πŸ“± Cross-platform: Works on both iOS and Android
  • 🎯 TypeScript Support: Full TypeScript definitions included
  • ⚑ High Performance: Built with React Native's new architecture (Fabric)
  • πŸš€ Expo Compatible: Works seamlessly with Expo managed and bare workflows
  • βœ… Platform-Supported BLE Advertising: Support for core BLE advertising data types that work reliably on both platforms
  • πŸ”§ Dynamic Updates: Update advertising data while advertising is active

πŸ“¦ Installation

React Native CLI

npm install munim-bluetooth-peripheral
# or
yarn add munim-bluetooth-peripheral

Expo

npx expo install munim-bluetooth-peripheral

Note: This library requires Expo SDK 50+ and works with both managed and bare workflows.

iOS Setup

For iOS, the library is automatically linked. However, you need to add the following to your Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to create a peripheral device</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app uses Bluetooth to create a peripheral device</string>

For Expo projects, add these permissions to your app.json:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSBluetoothAlwaysUsageDescription": "This app uses Bluetooth to create a peripheral device",
        "NSBluetoothPeripheralUsageDescription": "This app uses Bluetooth to create a peripheral device"
      }
    }
  }
}

Android Setup

For Android, add the following permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

For Expo projects, add these permissions to your app.json:

{
  "expo": {
    "android": {
      "permissions": [
        "android.permission.BLUETOOTH",
        "android.permission.BLUETOOTH_ADMIN",
        "android.permission.BLUETOOTH_ADVERTISE",
        "android.permission.BLUETOOTH_CONNECT",
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.ACCESS_COARSE_LOCATION"
      ]
    }
  }
}

⚑ Quick Start

Basic Usage

import {
  startAdvertising,
  stopAdvertising,
  setServices,
} from 'munim-bluetooth-peripheral';

// Start advertising with basic options
startAdvertising({
  serviceUUIDs: ['180D', '180F'],
  localName: 'My Device',
  manufacturerData: '0102030405',
});

// Set GATT services
setServices([
  {
    uuid: '180D',
    characteristics: [
      {
        uuid: '2A37',
        properties: ['read', 'notify'],
        value: 'Hello World',
      },
    ],
  },
]);

// Stop advertising
stopAdvertising();

Advanced Usage with Supported Advertising Data Types

import {
  startAdvertising,
  updateAdvertisingData,
  getAdvertisingData,
  type AdvertisingDataTypes,
} from 'munim-bluetooth-peripheral';

// Platform-supported advertising data configuration
const advertisingData: AdvertisingDataTypes = {
  // 0x01 - Flags (LE General Discoverable Mode, BR/EDR Not Supported)
  flags: 0x06,

  // 0x02-0x07 - Service UUIDs (fully supported)
  completeServiceUUIDs16: ['180D', '180F'],
  incompleteServiceUUIDs128: ['0000180D-0000-1000-8000-00805F9B34FB'],

  // 0x08-0x09 - Local Name (fully supported)
  completeLocalName: 'My Smart Device',
  shortenedLocalName: 'SmartDev',

  // 0x0A - Tx Power Level (fully supported)
  txPowerLevel: -12,

  // 0x14-0x15 - Service Solicitation (fully supported)
  serviceSolicitationUUIDs16: ['180D'],
  serviceSolicitationUUIDs128: ['0000180D-0000-1000-8000-00805F9B34FB'],

  // 0x16, 0x20, 0x21 - Service Data (fully supported)
  serviceData16: [
    { uuid: '180D', data: '0102030405' },
    { uuid: '180F', data: '060708090A' },
  ],
  serviceData32: [
    { uuid: '0000180D-0000-1000-8000-00805F9B34FB', data: '0B0C0D0E0F' },
  ],

  // 0x19 - Appearance (partial support)
  appearance: 0x03c0, // Generic Watch

  // 0x1F - Service Solicitation (32-bit) (fully supported)
  serviceSolicitationUUIDs32: ['0000180D'],

  // 0xFF - Manufacturer Specific Data (fully supported)
  manufacturerData: '4C000215FDA50693A4E24FB1AFCFC6EB0764782500010001C5',
};
};

// Start advertising with supported data
startAdvertising({
  serviceUUIDs: ['180D', '180F'],
  advertisingData: advertisingData,
});

// Update advertising data dynamically
updateAdvertisingData({
  flags: 0x04,
  completeLocalName: 'Updated Device Name',
  txPowerLevel: -8,
});

// Get current advertising data
const currentData = await getAdvertisingData();
console.log('Current advertising data:', currentData);

πŸ”§ API Reference

Functions

startAdvertising(options)

Starts BLE advertising with the specified options.

Parameters:

  • options (object):
    • serviceUUIDs (string[]): Array of service UUIDs to advertise
    • localName? (string): Device name (legacy support)
    • manufacturerData? (string): Manufacturer data in hex format (legacy support)
    • advertisingData? (AdvertisingDataTypes): Platform-supported advertising data

updateAdvertisingData(advertisingData)

Updates the advertising data while advertising is active.

Parameters:

  • advertisingData (AdvertisingDataTypes): New advertising data

getAdvertisingData()

Returns a Promise that resolves to the current advertising data.

Returns: Promise

stopAdvertising()

Stops BLE advertising.

setServices(services)

Sets GATT services and characteristics.

Parameters:

  • services (array): Array of service objects

Types

AdvertisingDataTypes

Platform-supported interface for BLE advertising data types:

interface AdvertisingDataTypes {
  // 0x01 - Flags (partial support)
  flags?: number;

  // 0x02-0x07 - Service UUIDs (fully supported)
  incompleteServiceUUIDs16?: string[];
  completeServiceUUIDs16?: string[];
  incompleteServiceUUIDs32?: string[];
  completeServiceUUIDs32?: string[];
  incompleteServiceUUIDs128?: string[];
  completeServiceUUIDs128?: string[];

  // 0x08-0x09 - Local Name (fully supported)
  shortenedLocalName?: string;
  completeLocalName?: string;

  // 0x0A - Tx Power Level (fully supported)
  txPowerLevel?: number;

  // 0x14-0x15 - Service Solicitation (fully supported)
  serviceSolicitationUUIDs16?: string[];
  serviceSolicitationUUIDs128?: string[];

  // 0x16, 0x20, 0x21 - Service Data (fully supported)
  serviceData16?: Array<{
    uuid: string;
    data: string;
  }>;
  serviceData32?: Array<{
    uuid: string;
    data: string;
  }>;
  serviceData128?: Array<{
    uuid: string;
    data: string;
  }>;

  // 0x19 - Appearance (partial support)
  appearance?: number;

  // 0x1F - Service Solicitation (32-bit) (fully supported)
  serviceSolicitationUUIDs32?: string[];

  // 0xFF - Manufacturer Specific Data (fully supported)
  manufacturerData?: string;
}

Supported BLE Advertising Data Types

Hex Type Name Description Support Level Example
0x01 Flags Basic device capabilities Partial flags: 0x06
0x02-0x07 Service UUIDs Service UUIDs offered Full completeServiceUUIDs16: ['180D']
0x08-0x09 Local Name Device name Full completeLocalName: 'My Device'
0x0A Tx Power Level Transmit power in dBm Full txPowerLevel: -12
0x14-0x15 Service Solicitation Services being sought Full serviceSolicitationUUIDs16: ['180D']
0x16, 0x20, 0x21 Service Data Data associated with services Full serviceData16: [{uuid: '180D', data: '010203'}]
0x19 Appearance Appearance category Partial appearance: 0x03C0
0x1F Service Solicitation (32-bit) 32-bit services being solicited Full serviceSolicitationUUIDs32: ['0000180D']
0xFF Manufacturer Specific Data Vendor-defined data Full manufacturerData: '4748494A4B4C4D4E'

Note: This library focuses on reliability and platform compatibility. Advanced BLE features like mesh networking, LE Audio, indoor positioning, etc., are not supported due to platform limitations.

πŸ“– Usage Examples

Health Device Example

import { startAdvertising, setServices } from 'munim-bluetooth-peripheral';

// Health device advertising
startAdvertising({
  serviceUUIDs: ['180D', '180F'], // Heart Rate, Battery Service
  advertisingData: {
    flags: 0x06, // LE General Discoverable Mode, BR/EDR Not Supported
    completeLocalName: 'Health Monitor',
    appearance: 0x03c0, // Generic Watch
    txPowerLevel: -8,
    manufacturerData: '0102030405', // Custom health data
    serviceData16: [
      { uuid: '180D', data: '6400' }, // Heart rate: 100 bpm
      { uuid: '180F', data: '64' }, // Battery: 100%
    ],
  },
});

// Set up GATT services
setServices([
  {
    uuid: '180D', // Heart Rate Service
    characteristics: [
      {
        uuid: '2A37', // Heart Rate Measurement
        properties: ['read', 'notify'],
        value: '6400', // 100 bpm
      },
    ],
  },
  {
    uuid: '180F', // Battery Service
    characteristics: [
      {
        uuid: '2A19', // Battery Level
        properties: ['read', 'notify'],
        value: '64', // 100%
      },
    ],
  },
]);

Smart Home Device Example

import {
  startAdvertising,
  updateAdvertisingData,
} from 'munim-bluetooth-peripheral';

// Smart home device
startAdvertising({
  serviceUUIDs: ['1812', '180F'], // HID, Battery Service
  advertisingData: {
    flags: 0x04, // LE General Discoverable Mode
    completeLocalName: 'Smart Light Bulb',
    appearance: 0x03c1, // Generic Light Fixture
    uri: 'https://myhome.com/light1',
    manufacturerData: '0102030405', // Custom light data
    serviceData16: [
      { uuid: '1812', data: '01' }, // HID: Keyboard
      { uuid: '180F', data: '64' }, // Battery: 100%
    ],
  },
});

// Update advertising data when light state changes
updateAdvertisingData({
  manufacturerData: '0102030406', // Updated light data
  serviceData16: [
    { uuid: '1812', data: '02' }, // HID: Mouse
    { uuid: '180F', data: '50' }, // Battery: 80%
  ],
});

Basic Peripheral Setup

import React, { useEffect } from 'react';
import {
  startAdvertising,
  stopAdvertising,
  setServices,
  addListener,
  removeListeners,
} from 'munim-bluetooth-peripheral';

const MyPeripheral = () => {
  useEffect(() => {
    // Configure services
    setServices([
      {
        uuid: '1800', // Generic Access Service
        characteristics: [
          {
            uuid: '2a00', // Device Name
            properties: ['read'],
            value: 'MyDevice',
          },
          {
            uuid: '2a01', // Appearance
            properties: ['read'],
            value: '0x03C0', // Generic Computer
          },
        ],
      },
      {
        uuid: '1801', // Generic Attribute Service
        characteristics: [
          {
            uuid: '2a05', // Service Changed
            properties: ['indicate'],
          },
        ],
      },
    ]);

    // Start advertising
    startAdvertising({
      serviceUUIDs: ['1800', '1801'],
      localName: 'MyReactNativePeripheral',
    });

    // Cleanup on unmount
    return () => {
      stopAdvertising();
      removeListeners('connectionStateChanged');
    };
  }, []);

  return <Text>Peripheral is running...</Text>;
};

Custom Service with Notifications

import React, { useState, useEffect } from 'react';
import {
  startAdvertising,
  stopAdvertising,
  setServices,
  addListener,
} from 'munim-bluetooth-peripheral';

const SensorPeripheral = () => {
  const [sensorValue, setSensorValue] = useState(0);

  useEffect(() => {
    // Create a custom sensor service
    setServices([
      {
        uuid: '12345678-1234-5678-1234-56789abcdef0',
        characteristics: [
          {
            uuid: 'abcdefab-1234-5678-1234-56789abcdef0',
            properties: ['read', 'notify'],
            value: sensorValue.toString(),
          },
          {
            uuid: 'fedcbaab-1234-5678-1234-56789abcdef0',
            properties: ['write'],
          },
        ],
      },
    ]);

    startAdvertising({
      serviceUUIDs: ['12345678-1234-5678-1234-56789abcdef0'],
      localName: 'SensorPeripheral',
    });

    // Listen for connection events
    addListener('connectionStateChanged', (state) => {
      console.log('Connection state:', state);
    });

    // Simulate sensor updates
    const interval = setInterval(() => {
      setSensorValue((prev) => prev + 1);
    }, 1000);

    return () => {
      clearInterval(interval);
      stopAdvertising();
    };
  }, [sensorValue]);

  return <Text>Sensor Value: {sensorValue}</Text>;
};

πŸ” Troubleshooting

Common Issues

  1. Permission Denied: Ensure you have the necessary Bluetooth permissions in your app
  2. Advertising Not Starting: Check that Bluetooth is enabled on the device
  3. Services Not Visible: Verify that your service UUIDs are properly formatted

Expo-Specific Issues

  1. Development Build Required: This library requires a development build in Expo. Use npx expo run:ios or npx expo run:android
  2. Permissions Not Working: Make sure you've added the permissions to your app.json as shown in the setup section
  3. Build Errors: Ensure you're using Expo SDK 50+ and have the latest Expo CLI

Debug Mode

Enable debug logging by setting the following environment variable:

export REACT_NATIVE_BLUETOOTH_DEBUG=1

πŸ‘ Contributing

We welcome contributions! Please see our Contributing Guide for details on how to submit pull requests, report issues, and contribute to the project.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Star the Munim Technologies repo on GitHub to support the project