0

I have a question related to sending binary data from a Raspberry Pi to web client over WebRTC data channel. I have actually found a solution, but I believe it may be inefficient, and I'm not sure exactly why it works.

Basically, I have a UV4L server with WebRTC data channels enabled. My goal is to send data gathered over I2C to a web client over WebRTC. The UV4L documentation explains that a Unix domain socket must be created and data is passed through the socket from the UV4L server and the application running on the Raspberry. I used C code in my C++ project, since I am more familiar with the language. This is how I'm creating the socket in my application code. The UV4L server is configured to create a connection with the appropriate socket.

      struct thread_info *info = (struct thread_info *)args;
      int fd = 0, connfd = 0, returned_len = 0;

      fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
      if (fd < 0) {
          fprintf(stderr, "Failed to create socket file descriptor\n");
          exit(1);
       }

       struct sockaddr_un addr;
       addr.sun_family = AF_UNIX;
       strncpy(addr.sun_path, "/tmp/uv4l.socket", sizeof(addr.sun_path)-1);

       bind(fd, (struct sockaddr *) &addr, sizeof(addr));
       if (listen(fd, 10)) {
           fprintf(stderr, "Failed to listen on UNIX socket %d\n", errno);
           exit(1);
       }
       socklen_t socket_length = sizeof(addr);
       connfd = accept(fd,(struct sockaddr *)&addr, &socket_length);
       if (connfd < 0) {
           fprintf(stderr, "Failed to accept socket connection\n");
           exit(1);
       }
       info->socketfd = connfd;

This connection is successful. I then use the file descriptor in another thread to send the data. The I2C library I'm using (pigpio) allows to copy data into as char * buffer, which I define char buffer[nb_reads];

I try to send this data using send directly, but I observe no messages on the other side of my data channel (browser). It's only when I encode the data as a base64 string that I actually get the expected result.

    if (total_read > 0) {
        size_t encoded_length; 
        unsigned char *encoded = base64_encode((const unsigned char*)buffer, total_read, &encoded_length);
        ssize_t sent = send(info->socketfd, encoded, encoded_length, MSG_EOR);
        if (sent < 0) {
            fprintf(stderr, "Failed to send all necessary MPU6050 data");
        }
        free(encoded);
    }

Why is it that I cannot just send the byte array directly?

Roni Peled
  • 38
  • 4
  • You should check and print the return value of accept. It might be EINTR (signal occurred) which means you should just try again. – stark Jan 29 '19 at 21:17
  • The return value of accept indicates success. As explained in the question, sending the data as base64 encoded works fine. – Roni Peled Jan 29 '19 at 23:40

1 Answers1

0

WebRTC data channels can handle messages in two different binaryTypes: either Blob or ArrayBuffer. The latter is the only type of messages that UV4L supports (at the moment) and that expects to send or receive to/from the other peer (e.g. the browser). In other words, make sure the browser is interpreting the data as an ArrayBuffer.

lproj
  • 1
  • 1
  • No onmessage event occurs at all. As such, there is no event to expect data as any binary type. – Roni Peled Jan 29 '19 at 23:41
  • hmm.. strange, can you try to send a new buffer by adding a final '\0' char to the original non-encoded buffer and see if onmessage is triggered? or can you try a simple buffer of 6 chars like {'H','e','l,'l','o','\0'} – lproj Jan 30 '19 at 00:07
  • Will do! I'll get back to your shortly – Roni Peled Jan 30 '19 at 03:03