You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2020/12/30 01:15:37 UTC

[GitHub] [incubator-nuttx-apps] yjdwbj commented on a change in pull request #541: added: Using nRF24L01+ as A Bluetooth Low Energy Broadcaster/Beacon

yjdwbj commented on a change in pull request #541:
URL: https://github.com/apache/incubator-nuttx-apps/pull/541#discussion_r549903670



##########
File path: examples/nrf24l01_btle/nrf24l01_btle.c
##########
@@ -0,0 +1,635 @@
+/****************************************************************************
+ * examples/nrf24l01_btle/nrf24l01_btle.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <debug.h>
+
+#include <nuttx/signal.h>
+#include <nuttx/sensors/dhtxx.h>
+#include <nuttx/wireless/nrf24l01.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <poll.h>
+#include <fcntl.h>
+
+#include "nrf24l01_btle.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#define DEV_NAME   "/dev/nrf24l01"
+
+#ifndef STDIN_FILENO
+#  define STDIN_FILENO 0
+#endif
+
+#ifdef CONFIG_WL_NRF24L01_RXSUPPORT
+/* If RX support is enabled, poll both stdin and the message reception */
+#  define N_PFDS  2
+#else
+/* If RX support is not enabled, we cannot poll the wireless device */
+#  define N_PFDS  1
+#endif
+
+static struct pollfd pfds[N_PFDS];
+#define DEFAULT_TXPOWER    -6    /* (0, -6, -12, or -18 dBm) */
+
+/* logical BTLE channel number (37-39) */
+
+const uint8_t channel[3] =
+  {
+    37, 38, 39
+  };
+
+/* physical frequency (2400+x MHz)  */
+
+const uint8_t frequency[3] =
+  {
+    2, 26, 80
+  };
+
+const uint8_t adve_name[5] =
+  {
+    'n', 'R', 'F', '2', '4'
+  };
+
+/**
+ * This is a rather convoluted hack to extract the month number
+ * from the build date in the __DATE__ macro using a small hash
+ * function + lookup table. Since all inputs are const, this can
+ * be fully resolved by the compiler and saves over 200 bytes of code.
+ */
+
+#define month(m) month_lookup[ (( ((( (m[0] % 24) * 13) +\
+                               m[1]) % 24) * 13) + m[2]) % 24 ]
+
+const uint8_t month_lookup[24] =
+  {
+    0, 6, 0, 4, 0, 1, 0, 17,
+    0, 8, 0, 0, 3, 0, 0, 0,
+    18, 2, 16, 5, 9, 0, 1, 7
+  };
+
+struct btle_adv_pdu buffer;
+volatile bool quit;
+
+uint8_t current = 0;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+uint8_t swapbits(uint8_t a)
+{
+  /* reverse the bit order in a single byte */
+
+  uint8_t v = 0;
+  if (a & 0x80) v |= 0x01;
+  if (a & 0x40) v |= 0x02;
+  if (a & 0x20) v |= 0x04;
+  if (a & 0x10) v |= 0x08;
+  if (a & 0x08) v |= 0x10;
+  if (a & 0x04) v |= 0x20;
+  if (a & 0x02) v |= 0x40;
+  if (a & 0x01) v |= 0x80;
+  return v;
+}
+
+/* see BT Core Spec 4.0, Section 6.B.3.2 */
+
+static inline void whiten(uint8_t len)
+{
+  uint8_t i;
+  uint8_t * buf = (uint8_t *)&buffer;
+
+  /* initialize LFSR with current channel, set bit 6 */
+
+  uint8_t lfsr = channel[current] | 0x40;
+
+  while (len--)
+    {
+      uint8_t res = 0;
+
+      /* LFSR in "wire bit order" */
+
+      for (i = 1; i; i <<= 1)
+        {
+          if (lfsr & 0x01)
+            {
+              lfsr ^= 0x88;
+              res |= i;
+            }
+
+          lfsr >>= 1;
+        }
+
+      *(buf++) ^= res;
+    }
+}
+
+/* see BT Core Spec 4.0, Section 6.B.3.1.1 */
+
+static inline void crc(uint8_t len, uint8_t * dst)
+{
+  uint8_t i;
+  uint8_t * buf = (uint8_t *)&buffer;
+
+  /**
+   * initialize 24-bit shift register in "wire bit order"
+   * dst[0] = bits 23-16, dst[1] = bits 15-8, dst[2] = bits 7-0.
+   **/
+
+  dst[0] = 0xaa;
+  dst[1] = 0xaa;
+  dst[2] = 0xaa;
+
+  while (len--)
+    {
+      uint8_t d = *(buf++);
+      for (i = 1; i; i <<= 1, d >>= 1)
+        {
+          /**
+           * save bit 23 (highest-value),
+           * left-shift the entire register by one
+           **/
+
+          uint8_t t = dst[0] & 0x01;         dst[0] >>= 1;
+          if (dst[1] & 0x01) dst[0] |= 0x80; dst[1] >>= 1;
+          if (dst[2] & 0x01) dst[1] |= 0x80; dst[2] >>= 1;
+
+          /**
+           * if the bit just shifted out (former bit 23) and the incoming
+           * data bit are not equal (i.e. bit_out ^ bit_in == 1) => toggle
+           * tap bits
+           */
+
+          if (t != (d & 1))
+            {
+              /**
+               * toggle register tap bits (=XOR with 1)
+               * according to CRC polynom
+               **/
+
+              /* 0b11011010 inv. = 0b01011011 ^= x^6+x^4+x^3+x+1 */
+
+              dst[2] ^= 0xda;
+
+              /* 0b01100000 inv. = 0b00000110 ^= x^10+x^9 */
+
+              dst[1] ^= 0x60;
+            }
+        }
+    }
+}
+
+/* change buffer contents to "wire bit order" */
+
+static inline void swapbuf(uint8_t len)
+{
+  uint8_t * buf = (uint8_t *)&buffer;
+  while (len--)
+    {
+      uint8_t a = *buf;
+      uint8_t v = 0;
+      *(buf++) = swapbits(a);
+    }
+}
+
+#ifdef CONFIG_DEBUG_WIRELESS
+void nrf24_dumpbuffer(FAR const uint8_t *outbuf)
+{
+  syslog(LOG_INFO, "Hexdump buffer\n");
+  syslog(LOG_INFO,
+         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+          outbuf[0], outbuf[1], outbuf[2], outbuf[3], outbuf[4],
+          outbuf[5], outbuf[6], outbuf[7]);
+  syslog(LOG_INFO,
+         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+          outbuf[8], outbuf[9], outbuf[10], outbuf[11], outbuf[12],
+          outbuf[13], outbuf[14], outbuf[15]);
+  syslog(LOG_INFO,
+         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+          outbuf[16], outbuf[17], outbuf[18], outbuf[19], outbuf[20],
+          outbuf[21], outbuf[22], outbuf[23]);
+  syslog(LOG_INFO,
+         "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",
+          outbuf[24], outbuf[25], outbuf[26], outbuf[27], outbuf[28],
+          outbuf[29], outbuf[30], outbuf[31]);
+}
+#endif
+
+int nrf24_cfg(int fd)
+{
+  int error = 0;
+
+  uint32_t rf = NRF24L01_MIN_FREQ + frequency[current];
+  int32_t txpow = DEFAULT_TXPOWER;
+
+  /**
+   * if using RATE_1Mbps from include/nuttx/wireless/nrf24l01.h,
+   * tools/checkpatch.sh report error: Mixed case identifier found.
+   **/
+
+  nrf24l01_datarate_t datarate = 0; /* RATE_1Mbps */
+  nrf24l01_retrcfg_t retrcfg =
+    {
+      .count = 0,
+      .delay = 3 /* DELAY_1000us */
+    };
+
+  uint32_t addrwidth = 4;
+
+  uint8_t pipes_en = (1 << 0);  /* Only pipe #0 is enabled */
+
+  /**
+   * Define the pipe #0 parameters (AA enabled and dynamic payload length)
+   * the address must be 0x8e89bed6.
+   **/
+
+  nrf24l01_pipecfg_t pipe0cfg =
+    {
+     .en_aa = false,
+     .payload_length = 32,
+     .rx_addr =
+        {
+          swapbits(0x8e), swapbits(0x89), swapbits(0xbe), swapbits(0xd6)
+        }
+    };
+
+  nrf24l01_pipecfg_t *pipes_cfg[NRF24L01_PIPE_COUNT] =
+    {
+      &pipe0cfg, 0, 0, 0, 0, 0
+    };
+
+  nrf24l01_state_t primrxstate;
+
+#ifdef CONFIG_WL_NRF24L01_RXSUPPORT
+  primrxstate = ST_RX;
+#else
+  primrxstate = ST_POWER_DOWN;
+#endif
+
+  /* Set radio parameters */
+
+  ioctl(fd, NRF24L01IOC_SETRETRCFG,
+        (unsigned long)((nrf24l01_retrcfg_t *)&retrcfg));
+
+  ioctl(fd, WLIOC_SETRADIOFREQ, (unsigned long)((uint32_t *)&rf));
+  ioctl(fd, WLIOC_SETTXPOWER, (unsigned long)((int32_t *)&txpow));
+  ioctl(fd, NRF24L01IOC_SETDATARATE,
+        (unsigned long)((nrf24l01_datarate_t *)&datarate));
+
+  ioctl(fd, NRF24L01IOC_SETADDRWIDTH,
+        (unsigned long)((uint32_t *)&addrwidth));
+
+  /* set advertisement address: 0x8E89BED6 (bit-reversed -> 0x6B7D9171) */
+
+  ioctl(fd, NRF24L01IOC_SETTXADDR,
+           (unsigned long)((uint8_t *)&pipe0cfg.rx_addr));
+
+  ioctl(fd, NRF24L01IOC_SETPIPESCFG,
+        (unsigned long)((nrf24l01_pipecfg_t **)&pipes_cfg));
+  ioctl(fd, NRF24L01IOC_SETPIPESENABLED,
+        (unsigned long)((uint8_t *)&pipes_en));
+
+  ioctl(fd, NRF24L01IOC_SETSTATE,
+        (unsigned long)((nrf24l01_state_t *)&primrxstate));
+
+  return error;
+}
+
+int nrf24_open(void)
+{
+  int fd;
+
+  fd = open(DEV_NAME, O_RDWR);
+
+  if (fd < 0)
+    {
+      perror("Cannot open nRF24L01 device");
+    }
+  else
+    {
+      nrf24_cfg(fd);
+    }
+
+  return fd;
+}
+
+int nrf24_send(int wl_fd, uint8_t * buf, uint8_t len)
+{
+  int ret;
+
+  wlinfo("send buffer len %d\n", len);
+  ret = write(wl_fd, buf, len);
+  if (ret < 0)
+    {
+      wlerr("Error sending packet\n");
+      return ret;
+    }
+
+  return OK;
+}
+
+static inline void random_mac(void)

Review comment:
       Hi, @btashton . I have did test of your suggestion, If using libc `arc4random_buf ` , it dependency  enable `CONFIG_CRYPTO_RANDOM_POOL`.  if enable ` CONFIG_CRYPTO_RANDOM_POOL` and `CONFIG_DEBUG_FEATURES` I got report that `arm-none-eabi-ld: region `flash' overflowed by 1104 bytes` on stm32f103-minimum. Also, I  call libc `arc4random_buf` to generate random MAC, this app not working, which means it not discovered  by BLE scanner.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org