Is it possible to transfer files using web-bluetooth technology?

As I work on developing an embedded system that counts the number of cars, saves their speed and time data in a logs file using rsyslog. Simultaneously, I am creating a web-API (in Typescript/Angular with Electron for Desktop usage and later Web as well) that allows users to upload these logs and store them locally on their laptops.

I have successfully set up a GATT server and can acquire simple data like battery level and status over Web-Bluetooth. However, I am unsure if it is possible to send/receive a file using Web-Bluetooth or perhaps send it piece by piece.

My attempt at sending the file in pieces involved dividing the file size by 512 bytes per frame and transmitting X frame(s) to the Web-App. Unfortunately, I encountered issues after a few days of trying this method. This led me to discover information on Bluetooth's website about the 'Object Transfer Service' available with GATT. However, upon further investigation, it appears that this service primarily supports bulk data transfer via a separate L2CAP connection orientel channel, which raised questions about the possibility of sending files.

Considering the challenges faced with Web-Bluetooth, I am contemplating whether it would be more feasible to modify my plan and utilize a different protocol for transferring files between the laptop and the embedded system, specifically for tasks such as sending configuration files and parameters.

Answer №1

After experimenting with different approaches, I've come up with a solution that seems to work quite effectively. Essentially, I'm dividing my Uint8Array[] into packets of 512 bytes for transmission, writing, and reading. Below is the TypeScript code I've used:

async getFile() {
    let file: string = '';
    let value: string = 'begin';
    let returnedValue = null;

    while (value != '') {
      try {
        returnedValue = await this.characteristicScheduling.readValue();
        value = String.fromCharCode.apply(null, new Uint8Array(returnedValue.buffer));
        console.log(value);
        file= file.concat(value);

      } catch(e) {
        console.log(e);
      }
    }

    console.log('file: ' + file);
}

And here's the write function:

wait(ms: number) {
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
      end = new Date().getTime();
    }
}

pushFile() {
    let file= this.getFileContent();
    let value: string;
    let valueBytes = null;
    console.log(file);

    while (file.length > 0) {
      // Copy the first 512 bytes
      value = file.substr(0, 512);
      // Remove the first 512 bytes
      scheduling = file.substr(512)
      console.log(file);
      valueBytes = new TextEncoder().encode(value);

      console.log(valueBytes);
      const promise = this.characteristic.writeValue(valueBytes);
      promise.then(val => {
        console.log(val);
      });
      // The wait is isn't mandatory .. but just in case my embedded system is very busy
      this.wait(100);
    }

    // Send empty frame to notify the Embedded system that it's the end of transmission
    valueBytes = new TextEncoder().encode('');
    const promise = this.characteristic.writeValue(valueBytes);
      promise.then(val => {
        console.log(val);
      });
}

For more information on Web Bluetooth characteristics, refer to this link.

As an embedded engineer, my web-coding skills may not be perfect. Feel free to provide recommendations on how to optimize this code. I hope this code snippet proves helpful to others.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

react component not displaying image

I must admit, this might be a silly question but I'm just starting out in web development. My goal is to create a clickable image component that redirects to another page on the website. However, despite not encountering any errors, the image is not ...

Navigating Unknown Properties in Angular: A Guide to Iterating Through Arrays

I'm having trouble coming up with a title for my question. I want to loop through an array of dynamic objects coming from a database, but I don't know the properties of the objects. Here's an example of the array object: [{ "id": 9, ...

The tooltip menu options in material ui are displaying in a different location in the window rather than below the button icon. How can this issue be resolved?

I'm having trouble implementing a tooltip on an option menu icon and it's not working as expected. Here is my code: export default function FadeMenu() { const [ anchorEl, setAnchorEl ] = React.useState(null) const bus = Bus() const o ...

Can you explain the concept of being "well-typed" in TypeScript?

The website linked below discusses the compatibility of TypeScript 2.9 with well-defined JSON. What exactly does "well-typed" JSON mean? As far as I understand, JSON supports 6 valid data types: string, number, object, array, boolean, and null. Therefore, ...

Minimization tools for compressing CSS and JavaScript documents

After deploying my application, I noticed that the loading time has significantly increased. Is there a way to compress CSS and JS files? I include only the necessary code in each page and occasionally use minified versions of JS. Thank you. ...

Using specific delimiters in Vue.js components when integrating with Django and Vue-loader

While working on my Django + Vue.js v3 app, I came across a helpful tool called vue3-sfc-loader. This allows me to easily render .vue files using Django, giving me the best of both worlds. The current setup allows Django to successfully render the .vue fil ...

Incorporate 3 additional compound filters with shuffle.js

Is there a way to add a third compound filter to the existing shuffle.js code provided below? // ES7 will have Array.prototype.includes. function arrayIncludes(array, value) { return array.indexOf(value) !== -1; } // Convert an array-like object to a r ...

Pull data from another domain's DIV using jQuery's load/ajax function

I need to load content from a different domain into a DIV on my JSP page. For example: $("#myDiv").load("https://www.google.com") The issue I'm facing is that the request is being blocked by the browser's same origin policy. I've explore ...

Accessing a JSON key using a JavaScript variable

Is there a way to dynamically replace the key "Argentina" in a JSON object with a javascript variable string? jQuery(document).ready(function() { $.getJSON('countries.json', function(data) { var output= data.Argentina[0].countryPho ...

What is the most effective way to extract content values from different divs for calculation using jQuery?

I am working on creating a function that retrieves the content values from the <div class="rowtabela"> div and reads the nodes of <div class="item v_...">. Check out my code below: <div class="adicionados" id=& ...

In the process of transforming my JavaScript code into JQuery

I'm struggling to convert my JavaScript code into jQuery, especially when it comes to calling the function for radio elements by name. The original JavaScript works fine, but I can't seem to get the jQuery version to work correctly. Index HTML ...

Is there a way to include e.preventDefault() within an ajax call?

After the user clicks the submit button on my form, the handleSubmit function is triggered. However, I am having trouble calling e.preventDefault() inside my AJAX call due to its asynchronous nature. How can this issue be resolved? class FormRegister ex ...

Sending parameters in GraphQL with Typescript results in an empty set of curly braces being returned

I am new to learning GraphQL with Typescript and I am trying to pass an argument in a GraphQL function to return something dynamically. I have been struggling with this issue for the past hour and could not find any solutions. Here are the relevant code sn ...

Steps for updating a specific item within an object in an array of MongoDB document

Consider the following data collection, for which I have some questions: { "_id" : ObjectId("4faaba123412d654fe83hg876"), "user_id" : 123456, "total" : 100, "items" : [ { ...

Activate a tooltip in Vuetify

I'm utilizing vuetify and have implemented a tooltip feature on a button. However, I do not want the tooltip to be displayed on hover or click; instead, I would like it to appear when a specific event is triggered. translate.vue <v-tooltip v-model ...

Navigating the issue of updateMany not functioning properly in mongoose and nodejs

I need assistance with updating the author name of a post whenever the user updates their profile name. My code is as follows: router('/:id', async (req, res) { if (req.body._id == req.params.id) { try { const user = await ...

Listening for dates in NodeJS and triggering callbacks

Is there a method or module available that allows me to monitor the date and trigger a specific action when a certain condition is met without relying on setTimeOut? What I am looking for: if(currentHour==="08:00:00"){ doJob() } EDIT : To clarify, wha ...

Vue.js - A dynamic parent component generates content based on data passed from a renderless child component

I am currently working on developing a system for generating buttons using vue 3 and vue-class-component. The main goal is to create a flexible button generation process, where the number of buttons generated can vary (it could be just one or multiple). Us ...

Sending POST Requests with Next.js Version 14

How can I send a POST request using axios in Next.js 14, I prefer axios but fetch is also okay. I have been getting an AxiosError: Network Error when I try to use axios and TypeError: fetch failed when using fetch. However, it works fine with Postman. I ...

Transitioning from using a jQuery get request to utilizing Vue.js

Looking to transition from JQuery-based js to Vue as a newcomer to JavaScript. Seeking guidance on making a get request and displaying the retrieved data. What approach would you recommend for this task? Here's the HTML snippet: <div> <di ...