Bluetooth connection refused - sockets

I am working on a Bluetooth project involving one Arduino (with Seeed bluetooth shield v2.0) and one ubuntu laptop. Basically, I want message exchanges between the Arduino and the laptop. I paired the Arduino bluetooth shield with the laptop. Then I use the code below (on the laptop) to test. The Arduino is set as a Slave. And the laptop sends a test message.
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv){
struct sockaddr_rc addr = {0};
int s, status;
char buf[1024] = {0};
char dest[18] = "00:0E:EA:CF:1E:62";
for (size_t i = 1; i <= 30; i++) {
addr.rc_channel = i;
str2ba(dest, &addr.rc_bdaddr);
// connect to server
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
if(status == 0) {
status = send(s, "Hello!", 6, 0);
status = recv(s, buf, sizeof(buf), 0);
if(status > 0)
printf("received %s\n", buf);
break;
}
}
if(status < 0)
perror("send error");
close(s);
return 0;
}
Below is the test code at Arduino side.
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 7
#define TxD 6
SoftwareSerial bt(RxD,TxD);
char buf[100];
size_t idx;
void setup() {
Serial.begin(9600);
bt.begin(9600);
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
setupBlueToothConnection();
}
void loop() {
Serial.println("Waiting ...");
idx = 0;
memset(buf, sizeof(buf), 0);
while(bt.available()){
buf[idx] = bt.read();
idx++;
}
while(idx >= 0){
bt.write(buf[idx]);
idx--;
}
delay(1000);
}
void setupBlueToothConnection() {
bt.print("AT");
delay(400);
bt.print("AT+DEFAULT"); // Restore all setup value to factory setup
delay(2000);
bt.print("AT+LADD?"); // Restore all setup value to factory setup
delay(2000);
bt.print("AT+NAMEProver"); // set the bluetooth name as "SeeedBTSlave"
delay(400);
bt.print("AT+PIN0000"); // set the pair code to connect
delay(400);
bt.print("AT+ROLE?");
delay(400);
bt.print("AT+AUTH0");
delay(400);
bt.flush();
}
I receive error message: "send error: Connection refused". What is the problem? Can some help me with this? Thanks!
Update: I guess it might be the problem with port number. But I checked the datasheet for Seeed Bluetooth shield v2.0 and has not found any clue regarding to setup port number.

Most common problem with Bluetooth on Arduino except for code is having Arduino connected to your PC over USB cable and trying to use Bluetooth, as far as I am aware most of the shields connect directly to hardware RX and TX of the Arduino board, which are the same ports used for USB communication to your PC.
So is your Arduino connected over a USB port to your PC?

Related

What buffer collects the data sent through TCP sockets on localhost?

I have a client and server connected through TCP sockets on localhost.
I check with getsockopt that the server's SO_SNDBUF is small and the client's SO_RCVBUF is small (in my case both are 64KB)
I send twenty 500KB buffers from the server to the client, but in the client I've added a sleep for 500ms after each recv and I've capped the client receive buffer to 1MB.
What I observe is that the server very quickly rids itself of the 10MB of data which then arrives at the client in the next several seconds. 7-8MB are consistently in the "ether" in my experiments.
My question is what is this "ether"? It's obviously some buffer somewhere but can one tell which buffer it is?
Here is my test program.
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <cstdio>
#include <vector>
#include <cstdlib>
#define PROXY 0
static std::vector<uint8_t> getRandomBuf() {
std::vector<uint8_t> buf;
buf.reserve(500 * 1024);
for (size_t i = 0; i < buf.capacity(); ++i) buf.push_back(rand() % 256);
return buf;
}
int server() {
auto sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0) return puts("socket fail");
sockaddr_in srv = {};
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = INADDR_ANY;
srv.sin_port = htons(7654);
int enable = 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) {
return puts("setsockopt fail");
}
if (bind(sd, (sockaddr*)&srv, sizeof(srv)) < 0) {
return puts("bind fail");
}
listen(sd, 3);
puts("listening...");
sockaddr_in client;
socklen_t csz = sizeof(client);
auto sock = accept(sd, (sockaddr*)&client, &csz);
if (sock < 0) return puts("accept fail");
{
int data;
socklen_t size = sizeof(data);
getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &data, &size);
printf("accepted: %d\n", int(data));
}
for (int i=0; i<20; ++i) {
auto buf = getRandomBuf();
puts("Server sending blob");
send(sock, buf.data(), buf.size(), 0);
puts(" Server completed send of blob");
}
while (true) std::this_thread::yield();
return close(sock);
}
int client() {
int sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0) return puts("socket fail");
sockaddr_in client = {};
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr("127.0.0.1");
#if PROXY
client.sin_port = htons(9654);
#else
client.sin_port = htons(7654);
#endif
if (connect(sd, (sockaddr*)&client, sizeof(client)) < 0) {
return puts("connect fail");
}
{
int data;
socklen_t size = sizeof(data);
getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &data, &size);
printf("connected: %d\n", int(data));
}
std::vector<uint8_t> buf(1024*1024);
while (true) {
auto s = recv(sd, buf.data(), buf.size(), 0);
if (s <= 0) {
puts("recv fail");
break;
}
printf("Client received %.1f KB\n", double(s)/1024);
#if !PROXY
std::this_thread::sleep_for(std::chrono::milliseconds(500));
#endif
}
return close(sd);
}
int main() {
std::thread srv(server);
std::this_thread::sleep_for(std::chrono::milliseconds(300)); // give time for the server to start
client();
srv.join();
return 0;
}
Note that in the test program there is a #define PROXY 0.
In another experiment with PROXY set to 1, I ditch the sleep and instead connect the client to a throttling proxy (Charles) and throttle the bandwidth to 400KB/s. In this case the server rids itself of the 10MB almost immediately and they arrive in course of ~20 seconds on the client. I assume that the proxy is buffering, though I don't see a configuration in this particular one for the buffer size.
This is all done hunting for another (likely bufferbloat) issue in which the server sends 10MB with 20 packets from Denver to Amsterdam over an Internet connection which does indeed have a 400KB/s bandwidth. In this case the server, much like the throttling proxy example from above, rids itself of the 10MB almost immediately, and they arrive over the next 20 seconds on the client, leading to 20 second delays for any subsequent messages. Had they not left the server, I would've been able to reorder the packets and send higher-priority ones in-between the ones from the 10MB blob, and not have the client suffer a 20 second delay due to network clog.

esp32 rest chuncked response

Im trying to know the real wifi speed capabilities of the esp32, and so i created a simple routine using a common library
void speedTest(AsyncWebServerRequest *request)
{
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
}
but when i make the GET request, the board reset itself and in serial monitor i see the following log:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
E (17770) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (17770) task_wdt: - async_tcp (CPU 0/1)
E (17770) task_wdt: Tasks currently running:
E (17770) task_wdt: CPU 0: IDLE0
E (17770) task_wdt: CPU 1: loopTask
E (17770) task_wdt: Aborting.
abort() was called at PC 0x40131b44 on core 0
I also have tried to reduce the file size and the download goes fine, but for my purpose is useless.
Someone has already meet and solved this problem ? im not really a lambda lover, alternately a different library more customizable, if is possible I would not like to reimplement all the http protocol over socket.
thanks in adavance for the help.
comeplete code:
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
AsyncWebServer server(80);
const char* ssid = "testSpeed";
const char* psw = "12345678";
void notFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "Not found");
}
void speedTest(AsyncWebServerRequest *request)
{
#if 1
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
#endif
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, psw);
WiFi.softAPConfig(local_ip, gateway, subnet);
server.on("/stream", HTTP_GET, speedTest);
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
Looks like the implementation of AsyncWebServer is not meant for long-running transactions, as it never resets the task watchdog. As a workaround you can increase the watchdog timeout to its maximum limit of 60 s or disable it entirely. It's controlled by the following options in sdkconfig:
CONFIG_ESP_TASK_WDT=y # Task Watchdog is enabled
CONFIG_ESP_TASK_WDT_PANIC=y # Panic (reset) is invoked on timeout
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30 # Timeout in seconds
The normal way to change those is to run idf.py menuconfig (where they appear under "Component config", "Common ESP-related") but you can just update the file "sdkconfig" directly.
Undo those changes after you're finished with your experiments, it's usually a good idea to keep the Task Watchdog enabled.

Why is pcap only capturing PTP messages in live capture mode?

I am using a Intel i210-T1 Network Interface Card.
I am running the avnu gptp client (https://github.com/Avnu/gptp) with:
sudo ./daemon_cl -S -V
The other side is a gPTP Master.
I want to live capture incoming UDP packets on an network interface with hardware timestamps.
I can see the UDP Packets with wireshark, so the packets are actually on the wire.
My problem is that pcap doesn't return any packets other than PTP (ethertype 0x88f7) at all.
Is this a bug or am i using pcap the wrong way?
I wrote a minimal example to show my problem.
The code prints:
enp1s0
returnvalue pcap_set_tstamp_type: 0
returnvalue pcap_set_tstamp_precision: 0
returnvalue pcap_activate: 0
and afterwards only:
packet received with ethertype:88f7
#include <iostream>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <pcap/pcap.h>
int main(int argc, char **argv)
{
char errbuf[PCAP_ERRBUF_SIZE];
std::string dev = "enp1s0";
pcap_t* pcap_dev;
int i = 0;
printf("%s\n", dev.c_str());
pcap_dev = pcap_create(dev.c_str(), errbuf);
if(pcap_dev == NULL)
{
printf("pcap_create(): %s\n", errbuf);
exit(1);
}
i = pcap_set_tstamp_type(pcap_dev, PCAP_TSTAMP_ADAPTER_UNSYNCED);
printf("returnvalue pcap_set_tstamp_type: %i\n", i);
i = pcap_set_tstamp_precision(pcap_dev, PCAP_TSTAMP_PRECISION_NANO);
printf("returnvalue pcap_set_tstamp_precision: %i\n", i);
i = pcap_activate(pcap_dev);
printf("returnvalue pcap_activate: %i\n", i);
struct pcap_pkthdr* pkthdr;
const u_char* bytes;
while (pcap_next_ex(pcap_dev, &pkthdr, &bytes))
{
struct ether_header* ethhdr = (struct ether_header*) bytes;
std::cout << "packet received with ethertype:" << std::hex << ntohs(ethhdr->ether_type) << std::endl;
}
}
The solution is to enable promiscuous mode by using function:
https://linux.die.net/man/3/pcap_set_promisc
promiscuous mode disables any filtering by lower layers so you get every message arriving on the interface.
int pcap_set_promisc(pcap_t *p, int promisc);
pcap_set_promisc() sets whether promiscuous mode should be set on a capture handle when the handle is activated. If promisc is non-zero, promiscuous mode will be set, otherwise it will not be set.
Return Value
pcap_set_promisc() returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.

Reading Ettus E310 Barometer over I2C, always returns No Such Device or Address (-1)

I've been trying to write a I2C device driver for the BMP 180 barometer and temperature sensor found on the E310 (as seen in sheet 9 of the schematic.) I have been basing my code off of the example driver given by bosch.
The driver requires function pointers to block read and write, as well as a sleep, which are basically the only original code:
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
void user_delay_ms(uint32_t period)
The problem I am having is that this driver (as well as simpler SMBUS command only programs I have written) have always failed to read or write the i2c address 0x77, where the sensor should be located on the bus.
readBytes for device ID 0x77: -1 - No such device or address
Even though my code seems to work for locations that other devices are located at (though I haven't done more than ping them)
Motion Sensor:
readBytes for device ID 0x69: 0 - Success
Temperature Sensor:
readBytes for device ID 0x19: 0 - Success
I was wondering either what is wrong with my code that the device would be completely unresponsive, or what hardware configuration am I missing that would explain the lack of communication with the barometer at 0x77.
I notice that the BMP-180 barometer is placed on the auxiliary i2c of the Gyro MPU-9150, but the wiring and datasheet make me think it is in pass through mode and not master mode. Just a thought I had though.
Here is all of the code I have that interacts with the bmpDriver.
Compiled with the following
gcc test.c -o test -std=c11 -D _DEFAULT_SOURCE
#include "bmp280.c"
#include <linux/i2c-dev-user.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
int file;
file = open("/dev/i2c-0", O_RDWR);
if(file < 0)
{
printf("Failed to open /dev/i2c-0\n");
close(file);
return -1;
}
if(ioctl(file, I2C_SLAVE, dev_id) < 0)
{
printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
close(file);
return -2;
}
int readBytes;
readBytes = i2c_smbus_read_block_data(file, reg_addr, data);
printf("readBytes for device ID 0x%x: %d - %s\n", dev_id, readBytes, strerror(errno));
close(file);
return readBytes;
}
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
int file;
file = open("/dev/i2c-0", O_RDWR);
if(file < 0)
{
printf("Failed to open /dev/i2c-0\n");
close(file);
return -1;
}
if(ioctl(file, I2C_SLAVE, dev_id) < 0)
{
printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
close(file);
return -2;
}
int writeBytes;
uint8_t shortLen = len;
writeBytes = i2c_smbus_write_block_data(file, reg_addr, shortLen, data);
printf("writeBytes for device ID 0x%x: %d - %s\n", dev_id, writeBytes, strerror(errno));
close(file);
return writeBytes;
}
void user_delay_ms(uint32_t period){
unsigned int sleep = period;
usleep(sleep * 1000);
}
int main(){
int8_t rslt;
struct bmp280_dev user_bmp;
user_bmp.dev_id = BMP280_I2C_ADDR_SEC;
user_bmp.intf = BMP280_I2C_INTF;
user_bmp.read = user_i2c_read;
user_bmp.write = user_i2c_write;
user_bmp.delay_ms = user_delay_ms;
rslt = bmp280_init(&user_bmp);
if (rslt == BMP280_OK) {
printf("Device found with chip id 0x%x\n", user_bmp.chip_id);
}
else {
printf("Device not found, exiting...\n");
return -1;
}
struct bmp280_config conf;
rslt = bmp280_get_config(&conf, &user_bmp);
conf.filter = BMP280_FILTER_COEFF_2;
conf.os_pres = BMP280_OS_16X;
conf.os_temp = BMP280_OS_4X;
conf.odr = BMP280_ODR_1000_MS;
rslt = bmp280_set_config(&conf, &user_bmp);
rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &user_bmp);
struct bmp280_uncomp_data ucomp_data;
uint8_t meas_dur = bmp280_compute_meas_time(&user_bmp);
printf("Measurement duration: %dms\r\n", meas_dur);
uint8_t i;
for (i = 0; (i < 10) && (rslt == BMP280_OK); i++) {
printf("Running measurement: %d\n", i+1);
user_bmp.delay_ms(meas_dur);
rslt = bmp280_get_uncomp_data(&ucomp_data, &user_bmp);
int32_t temp32 = bmp280_comp_temp_32bit(ucomp_data.uncomp_temp, &user_bmp);
uint32_t pres32 = bmp280_comp_pres_32bit(ucomp_data.uncomp_press, &user_bmp);
uint32_t pres64 = bmp280_comp_pres_64bit(ucomp_data.uncomp_press, &user_bmp);
double temp = bmp280_comp_temp_double(ucomp_data.uncomp_temp, &user_bmp);
double pres = bmp280_comp_pres_double(ucomp_data.uncomp_press, &user_bmp);
printf("UT: %d, UP: %d, T32: %d, P32: %d, P64: %d, P64N: %d, T: %f, P: %f\r\n", \
ucomp_data.uncomp_temp, ucomp_data.uncomp_press, temp32, \
pres32, pres64, pres64 / 256, temp, pres);
user_bmp.delay_ms(1000);
}
if(rslt != BMP280_OK){
printf("Result not okay at measurement: %d\n", i);
}
}
Before starting off with a speculation I would make sure that the transmission is actually reaching the sensor behind the gyro. Just use any scope to measure SCL and SDA. If the device is getting the transmission, the scope reading will provide additional information on where the device NAKs.
One difference between the BMP and the other i2c devices you were able to address that gave me multiple headaches in the past:
the BMP seems to require a repeated start condition between device address and register read.
As far as I can remember, standard i2c libraries do not support this and you usually have to build your own read / write functions using linux/i2c-dev.h.

TCP_FASTOPEN undeclared

I'm coding a small server that uses TCP Fast Open option through setsockopt(). However I am getting this error from gcc :
$gcc server.c
server.c: In function 'main':
server.c:35:34: error: 'TCP_FASTOPEN' undeclared (first use in this function)
if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen) == -1)
Here is the server's code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
int main(int argc, char *argv[])
{
short port = 45000;
int max_conn = 10;
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
printf("Couldn't create socket: %s\n", strerror(errno));
return -1;
}
struct sockaddr_in ssi;
ssi.sin_family = AF_INET;
ssi.sin_port = htons(port);
ssi.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&ssi, sizeof(struct sockaddr_in)) != 0)
{
printf("Couldn't bind socket: %s\n", strerror(errno));
return -1;
}
// TFO
int qlen = 5;
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) == -1)
{
printf("Couldn't set TCP_FASTOPEN option: %s\n", strerror(errno));
return -1;
}
if (listen(fd, max_conn) != 0)
{
printf("Could'nt listen on socket: %s\n", strerror(errno));
return -1;
}
struct sockaddr_in csi;
int clen = sizeof(csi);
int cfd = accept(fd, (struct sockaddr *)&csi, &clen);
return 0;
}
Why does gcc gives this error?
The macro TCP_FASTOPEN is located in include/uapi/linux/tcp.h in the kernel and its value is 23 so I tried to redefine it in my code, then it does compile and run but the option is not sent by the server as an answer to a TFO request (in the SYN-ACK).
Does anybody knows why? Is this related to the compilation issue?
/proc/sys/net/ipv4/tcp_fastopen needs to be set to 2 to enable server-side use of TCP fast open option:
The tcp_fastopen file can be used to view or set a value that enables the operation of different parts of the TFO functionality. Setting bit 0 (i.e., the value 1) in this value enables client TFO functionality, so that applications can request TFO cookies. Setting bit 1 (i.e., the value 2) enables server TFO functionality, so that server TCPs can generate TFO cookies in response to requests from clients. (Thus, the value 3 would enable both client and server TFO functionality on the host.)
Also, TCP_FASTOPEN macro needs to be included with #include <netinet/tcp.h>.
Looks like your glibc doesn't have support for TCP_FASTOPEN - even if your keernel has (since it's not available when you include standard socket headers). So you can't really use it using glibc glue code (of which setsockopt() is part of).