Socket TCP in linux - Client cannot insert username - sockets

I'm having troubles with implementing a signin/signup system with TCP/IP sockets.
So, whenever I want the user to signup, the client cannot insert the username, but he can insert the password. It looks like it is skipping one step.
Here is the code.
Client
void func(int sockfd)
{
char username[MAX], password[MAX];
int n, c;
bzero(username, sizeof(username));
printf("Enter the username : ");
n = 0;
while ((username[n++] = getchar()) != '\n')
;
write(sockfd, username, sizeof(username));
bzero(username, sizeof(username));
bzero(password, sizeof(password));
printf("Enter the password : ");
c = 0;
while ((password[c++] = getchar()) != '\n')
;
write(sockfd, password, sizeof(password));
bzero(username, sizeof(password));
}
...
int choice, ans;
func(sockfd);
bzero(buffer, 255);
n = read(sockfd, buffer, 255);
if(n < 0)
error("Error reading from socket");
printf("Server - %s", buffer);
scanf("%d", &choice);
write(sockfd, &choice, sizeof(int));
if(choice == 1) {
func(sockfd);
}
if(choice == 3) {
printf("Session terminated\n");
close(sockfd);
}
close(sockfd);
return 0;
Server
void func(int newsockfd)
{
char username[MAX], password[MAX];
int n;
bzero(username, MAX);
read(newsockfd, username, sizeof(username));
printf("From client: %s\n", username);
bzero(password, MAX);
read(newsockfd, password, sizeof(password));
printf("From client pass: %s\n", password);
while ((username[n++] = getchar()) != '\n')
;
write(newsockfd, username, sizeof(username));
}
int main(int argc, char *argv[]) {
func(newsockfd);
int num1, num2, ans, choice;
n = write(newsockfd, "Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n", strlen("Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n"));
if(n < 0) error("Error writing to socket");
read(newsockfd, &choice, sizeof(int));
switch(choice) {
case 1:
func(newsockfd);
break;
case 2:
break;
case 3:
close(newsockfd);
close(sockfd);
}
close(newsockfd);
close(sockfd);
return 0;
}
This is an example:

Ignoring the fact that the code provided is not complete code, the client and server are not even speaking the same protocol, so of course you are running into problems.
The client is sending the username and password to the server before it has even received the server's initial prompt.
The server is expecting the first input from the client to be the user's choice to the prompt, but the client is sending the username first, so the first few characters the server receives will be misinterpreted as an integer.
When the server does expect to receive a username and password, it sends back the username, which the client does not read.
You are also completely ignoring the return values of read() and write(). And you are not handling received strings properly, either.
With that said, try something more like this instead:
Shared
int sendAll(int sockfd, void *buf, size_t len)
{
char *pbuf = (char*) buf;
int n;
while (len > 0) {
n = send(sockfd, pbuf, len, 0);
if (n < 0) return n;
pbuf += n;
len -= n;
}
return 0;
}
int recvAll(int sockfd, void *buf, size_t len)
{
char *pbuf = (char*) buf;
int n;
while (len > 0) {
n = recv(sockfd, pbuf, len, 0);
if (n <= 0) return n;
pbuf += n;
len -= n;
}
return 1;
}
int sendInt32(int sockfd, int32_t value)
{
value = htonl(value);
return sendAll(sockfd, &value, sizeof(value));
}
int recvInt32(int sockfd, int32_t *value)
{
int n = recvAll(sockfd, value, sizeof(*value));
if (n == 1) *value = ntohl(*value);
return n;
}
int sendStr(int sockfd, const char *str)
{
int len = strlen(str);
int n = sendInt32(sockfd, len);
if (n == 0) n = sendAll(sockfd, str, len);
return n;
}
int recvStr(int sockfd, char **str)
{
*str = NULL;
int32_t len;
int n = recvInt32(sockfd, &len);
if (n <= 0) return n;
*str = malloc(len + 1);
if (*str == NULL) return -1;
n = recvAll(sockfd, *str, len);
if (n <= 0) {
free(*str);
*str = NULL;
return n;
}
(*str)[len] = '\0';
return 1;
}
Client
void func(int sockfd)
{
char input[MAX+1];
int n, c;
printf("Enter the username : ");
n = 0;
while ((n < MAX) && ((c = getchar()) != EOF) && (c != '\n')) {
input[n++] = (char) c;
}
input[n] = '\0';
if (sendStr(sockfd, input) < 0)
error("Error writing to socket");
printf("Enter the password : ");
n = 0;
while ((n < MAX) && ((c = getchar()) != EOF) && (c != '\n')) {
input[n++] = (char) c;
}
input[n] = '\0';
if (sendStr(sockfd, input) < 0)
error("Error writing to socket");
char *ans;
if (recvStr(sockfd, &ans) <= 0)
error("Error reading from socket");
printf("Server - %s: ", ans);
free(ans);
}
int main() {
int sockfd, choice;
char *str;
// connect to server...
sockfd = ...;
if (recvStr(sockfd, &str) <= 0)
error("Error reading from socket");
printf("Server - %s", str);
free(str);
scanf("%d", &choice);
if (sendInt32(sockfd, choice) < 0)
error("Error writing to socket");
switch (choice) {
case 1:
case 2:
func(sockfd);
break;
case 3:
printf("Session terminated\n");
break;
}
close(sockfd);
return 0;
}
Server
void func(int sockfd, int choice)
{
char *input;
if (recvStr(sockfd, &input) <= 0)
error("Error reading from socket");
printf("From client user: %s\n", input);
free(input);
if (recvStr(sockfd, &input) <= 0)
error("Error reading from socket");
printf("From client pass: %s\n", input);
free(input);
char *ans = (choice == 1) ? "Registered" : "Logged in";
if (sendStr(sockfd, ans) < 0)
error("Error writing to socket");
}
int main() {
int sockfd, clientsockfd, n;
int32_t choice;
// setup listening socket ...
sockfd = ...;
// accept client ...
clientsockfd = ...;
if (SendStr(clientsockfd, "Benvenuto, inserisci una scelta: \n1. Registrazione\n2. Login\n3. Esci\n") < 0)
error("Error writing to socket");
if (recvInt32(clientsockfd, &choice) < 0)
error("Error reading from socket");
switch (choice) {
case 1:
case 2:
func(clientsockfd, choice);
break;
case 3:
close(clientsockfd);
break;
}
close(sockfd);
return 0;
}

a) can you printf("choice: %d\n", choice);
b) I have problems to see if the socket is blocked by your first function call
c) most important - we have to focus on the fact, that you try to send serialized data (int) - that is totally other than sending plain text. Search google: "Network Byte Order":
//client
uint32_t choice;
choice = htons(choice);
write(sockfd, &choice, sizeof(choice));
//server
uint32_t choice;
read(newsockfd, &choice, sizeof(uint32_t));
choice = ntohs(choice);
switch(choice);

Related

Why is the client's file descriptor used while calling the recv and send funtions on both server and client sides?

TCPServer
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("socket failed!\n");
exit(0);
}
printf("Enter port: ");
int port;
scanf("%d",&port);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
int bind_ret = bind(fd, (struct sockaddr*)(&server), sizeof(server));
if(bind_ret == -1)
{
printf("bind failed!\n");
exit(0);
}
int listen_ret = listen(fd, 10);
if(listen_ret == -1)
{
printf("listen failed!\n");
exit(0);
}
struct sockaddr_in client;
int l = sizeof(client);
int client_fd = accept(fd, (struct sockaddr*)(&client), &l);
if(client_fd == -1)
{
printf("accept failed!\n");
exit(0);
}
while(1)
{
char msg_recv[50];
int recv_ret = recv(client_fd, msg_recv, sizeof(msg_recv),0);
if(recv_ret == -1)
{
printf("recv failed!\n");
exit(0);
}
msg_recv[recv_ret]='\0';
if(strcmp("bye",msg_recv)==0)
{
exit(0);
}
printf("Message recieved: %s\n",msg_recv);
char msg_send[50];
printf("Enter message: ");
scanf(" %s",msg_send);
int send_ret = send(client_fd, msg_send, strlen(msg_send),0);
if(send_ret == 0)
{
printf("send failed!\n");
}
if(strcmp("bye",msg_send) == 0)
exit(0);
}
}
TCPClient
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
int main()
{ int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("socket failed!\n");
exit(0);
}
int port;
printf("Enter port number: ");
scanf("%d",&port);
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_port = htons(port);
client.sin_addr.s_addr = INADDR_ANY;
int connect_ret = connect(fd, (struct sockaddr*)(&client), sizeof(client));
if(connect_ret == -1)
{
printf("connect failed!\n");
exit(0);
}
while(1)
{
printf("Enter message: ");
char msg_send[50];
scanf("%s",msg_send);
int send_ret = send(fd, msg_send, strlen(msg_send), 0);
if(send_ret == -1)
{
printf("send failed!\n");
exit(0);
}
if(strcmp("bye", msg_send)==0)
{
exit(0);
}
char msg_recv[50];
int recv_ret = recv(fd, msg_recv, sizeof(msg_recv), 0);
if(recv_ret == -1)
{
printf("recv failed!\n");
exit(0);
}
msg_recv[recv_ret]= '\0';
if(strcmp("bye", msg_recv) == 0)
exit(0);
printf("Message recieved: %s \n",msg_recv);
}
}
In the above program for Server, recv and send were called by passing client_fd as the argument, while in the program for Client, recv and send were called by passing fd as the argument. I wanted to know why on the server side we did not use its own socket file descriptor like we did on the client side?
The server’s fd descriptor is a listen()’ing socket. It can’t perform any I/O, only receive incoming client connections. accept() pulls a pending client connection from fd’s queue and returns a new socket descriptor that can perform I/O with that client.
The client’s fd descriptor is a connect()‘ing socket. It can perform I/O with the server once its connection has been accepted.

How to return to menu in Socket Client-Server

I've writen this code but it doesn't work correctly.
This is menu interface:
*************ENCODE_DECODE_BASE64**************
******* 1. Encode ********
******* 2. Decode ********
******* 3. Exit ********
***********************************************
When i choose 1, "Encode". The function runs but the process exits.
I want when I choose 1, the function to run and then after that, the menu to display again.
Can you help me?
Here is Clientcode:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024
// read filename
char *inputString(int size){
int test=0;
char *s=(char*)malloc(size);
do{
if(test!=0){
printf("File not found !!!!!!");
}
fgets(s,size,stdin);
test++;
}while(strlen(s)<=1);
return strtok(s,"\n");
}
int main(int argc, char *argv[]){
int sockfd;
struct sockaddr serverAddr; //server address
char buff[1024];
struct sockaddr_in inAddr;
long int sentBytes,revedBytes;
sockfd=socket(AF_INET,SOCK_STREAM,0); // create socket
if (sockfd == -1)
{
printf("ERROR opening socket\n");
return 1;
}
printf("Socket done\n");
inAddr.sin_family=AF_INET; //default
inAddr.sin_port=htons(5500); // service port
inet_aton("127.0.0.1",&inAddr.sin_addr);
//connectting
if(connect(sockfd,(struct sockaddr *)&inAddr,sizeof(struct sockaddr))<0){
printf("Connect failed.\n");
return 1;
}
printf("Connection accepted\n");
char *FileName; // file input
char *Result; // file return
int choice;
do{
printf("\n*************ENCODE_DECODE_BASE64**************");
printf("\n******* 1. Encode ********");
printf("\n******* 2. Decode ********");
printf("\n******* 3. Exit ********");
printf("\n***********************************************\n");
printf("Choice: ");
choice = getchar();
while(getchar() !='\n');
switch(choice)
{
case '1':
//demo encode////////////////////////////////////////
send(sockfd,"encode",5,0); // send to server when choose 1
printf("File Encode : ");
FileName = inputString(20);
FILE *fpt = fopen(FileName,"r");
if(fpt==NULL){
printf("File not found");
return -1;
}
printf("File Result: ");
Result = inputString(20);
FILE *ft = fopen(Result,"w");
while(!feof(fpt)){
if (fgets(buff,MAX,fpt) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft,"%s\n",buff);
}
}
printf("Encode done!thanks you !\n");
//close(sockfd);
fclose(fpt);fclose(ft);
return 0;
break;
//decode ///////////////////////////////////////////////
case '2':
send(sockfd,"decode",6,0);
printf("File Decode : ");
FileName = inputString(20);
FILE *fpt1 = fopen(FileName,"r");
if(fpt1==NULL){
printf("File not found");
return -1;
}
printf("File Result : ");
Result = inputString(20);
FILE *ft1 = fopen(Result,"w");
while(!feof(fpt1)){
if (fgets(buff,MAX,fpt1) != NULL ){
sentBytes=send(sockfd,buff,1024,0);
revedBytes=recv(sockfd,buff,1024,0);
fprintf(ft1,"%s",buff);
}
}
printf("Decode done ! thanks you !\n");
//close(sockfd);
fclose(fpt1);fclose(ft1);
return 0;
break;
///////////////////////////////////////////////////////
case '3':
printf("Thanks!\n");
break;
default: printf("wrong number, please try again!\n"); break;
//end choice///////////////////////////////////////
}
}while(choice!='3');
//end menu
//close(sockfd);
//return 0;
}
and here is ServerCode:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
void sig_chld(int signo) //child
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG))>0)
printf("child %d terminated\n", pid);
return;
}
int main()
{
int listen_sock, conn_sock;
int server_len, client_len,choice;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
char myb64[1024] = ""; //encode
char mydst[1024] = ""; //decode
int sentBytes,revedBytes,bytes_readi;
char buff[1024]; //buffer to send data
listen_sock = socket(AF_INET, SOCK_STREAM, 0); //create socket
if (listen_sock == -1)
{
printf("ERROR opening socket\n");
return 0;
}
printf("Socket done\n");
//Thiet lap dia chi server
server_address.sin_family = AF_INET; //default
inet_aton("127.0.0.1",&server_address.sin_addr); //ip server
server_address.sin_port = htons(5500); // port server
server_len = sizeof(server_address);
if(bind(listen_sock, (struct sockaddr *)&server_address,server_len)<0)
{
printf("ERROR on binding\n");
return 0;
}
printf("Bind done\n");
int check = listen(listen_sock,10);
if (check == -1)
{
printf("Error connect");
return 0;
}
printf("Waiting connect..\n");
while(1) {
client_len = sizeof(client_address);
conn_sock = accept(listen_sock,(struct sockaddr *)&client_address, &client_len);
if(conn_sock==-1){
printf("Error connect\n");
return 1;
}else{
printf("Accept new connection\n");
}
if(fork() == 0){
close(listen_sock);
do{
revedBytes = recv(conn_sock,buff,1024,0);
buff[revedBytes]='\0';
if(strcmp(buff,"mahoa")==0) choice=1;
else if(strcmp(buff,"giaima")==0) choice=2; else choice = 3;
switch(choice)
{
case 1:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client encode : %s\n",buff);
b64_encode(buff, myb64); //ma hoa
sentBytes=send(conn_sock,myb64,1024,0); //gui lai string da ma hoa cho client
}
close(conn_sock);//Dong ket noi cua client
exit(0);
break;
case 2:
while((revedBytes = recv(conn_sock,buff,1024,0)) > 0){
buff[revedBytes]='\0';
//printf("string send by client decode: %s\n",buff);
b64_decode(buff,mydst); // giaima
sentBytes=send(conn_sock,mydst,1024,0);
}
close(conn_sock);
exit(0);
break;
case 3:break;
}
}while(choice!=3);
break;
}
signal(SIGCHLD,sig_chld);
close(conn_sock);
}
return 1;
}

Customize (BLUEZ) HCI LE Advertising Report format

I would like to have the ability to customize HCI LE Advertising Report so that I can gather additional Service UUIDs without connecting to an IOS app (iPhone).
The BLUEZ hcitool (via the lescan option) returns an HCI LE Advertising Report per device as follows:
Num_Reports,
Event_Type[i],
Address_Type[i],
Address[i],
Length[i],
Data[i],
RSSI[i]
My code to retrieve this HCI LE Advertising Report is based on the hcitool.c cmd_lescan functions as follows:
static void print_eir(const uint8_t *eir, uint8_t eir_len, bool le)
{
info("print_eir");
uint16_t len = 0;
if (eir_len == 0)
return;
while (len < eir_len - 1) {
uint8_t field_len = eir[0];
const uint8_t *data = &eir[2];
uint8_t data_len;
char name[239], label[100];
uint8_t flags, mask;
int i;
/* Check for the end of EIR */
if (field_len == 0)
break;
len += field_len + 1;
/* Do not continue EIR Data parsing if got incorrect length */
if (len > eir_len) {
len -= field_len + 1;
break;
}
data_len = field_len - 1;
switch (eir[1]) {
case BT_EIR_FLAGS:
info("BT_EIR_FLAGS");
flags = *data;
mask = flags;
info("Flags: 0x%2.2x", flags);
for (i = 0; eir_flags_table[i].str; i++) {
if (flags & (1 << eir_flags_table[i].bit)) {
info(" %s",
eir_flags_table[i].str);
mask &= ~(1 << eir_flags_table[i].bit);
}
}
break;
case BT_EIR_UUID16_SOME:
info("BT_EIR_UUID16_SOME\n");
if (data_len < sizeof(uint16_t))
break;
print_uuid16_list("16-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID16_ALL:
info("BT_EIR_UUID16_ALL\n");
if (data_len < sizeof(uint16_t))
break;
print_uuid16_list("16-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_UUID32_SOME:
info("BT_EIR_UUID32_SOME\n");
if (data_len < sizeof(uint32_t))
break;
print_uuid32_list("32-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID32_ALL:
info("BT_EIR_UUID32_ALL\n");
if (data_len < sizeof(uint32_t))
break;
print_uuid32_list("32-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_UUID128_SOME:
info("BT_EIR_UUID128_SOME\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs (partial)",
data, data_len);
break;
case BT_EIR_UUID128_ALL:
info("BT_EIR_UUID128_ALL\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs (complete)",
data, data_len);
break;
case BT_EIR_NAME_SHORT:
info("BT_EIR_NAME_SHORT");
memset(name, 0, sizeof(name));
memcpy(name, data, data_len);
info("Name (short): %s", name);
break;
case BT_EIR_NAME_COMPLETE:
info("BT_EIR_NAME_COMPLETE");
memset(name, 0, sizeof(name));
memcpy(name, data, data_len);
info("Name (complete): %s", name);
break;
case BT_EIR_SERVICE_UUID128:
info("BT_EIR_SERVICE_UUID128\n");
if (data_len < 16)
break;
print_uuid128_list("128-bit Service UUIDs",
data, data_len);
break;
case BT_EIR_SERVICE_DATA:
info("BT_EIR_SERVICE_DATA\n");
if (data_len < 2)
break;
sprintf(label, "Service Data (UUID 0x%4.4x)",
get_le16(&data[0]));
print_hex_field(label, &data[2], data_len - 2);
break;
case BT_EIR_RANDOM_ADDRESS:
info("BT_EIR_RANDOM_ADDRESS\n");
if (data_len < 6)
break;
print_addr("Random Address", data, 0x01);
break;
case BT_EIR_PUBLIC_ADDRESS:
info("BT_EIR_PUBLIC_ADDRESS\n");
if (data_len < 6)
break;
print_addr("Public Address", data, 0x00);
break;
case BT_EIR_TX_POWER:
info("BT_EIR_TX_POWER");
if (data_len < 1)
break;
info("TX power: %d dBm", (int8_t) *data);
break;
case BT_EIR_SMP_OOB_FLAGS:
info("BT_EIR_SMP_OOB_FLAGS");
info("SMP OOB Flags: 0x%2.2x", *data);
break;
default:
sprintf(label, "Unknown EIR field 0x%2.2x", eir[1]);
print_hex_field(label, data, data_len);
break;
}
eir += field_len + 1;
}
if (len < eir_len && eir[0] != 0)
packet_hexdump(eir, eir_len - len);
}
static int print_advertising_devices(int dd, uint8_t filter_type)
{
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
struct hci_filter nf, of;
struct sigaction sa;
socklen_t olen;
int len;
info("print_advertising_devices");
olen = sizeof(of);
if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) {
error("Could not get socket options");
return -1;
}
hci_filter_clear(&nf);
hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
hci_filter_set_event(EVT_LE_META_EVENT, &nf);
if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {
error("Could not set socket options");
return -1;
}
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = sigint_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {
evt_le_meta_event *meta;
le_advertising_info *leinfo;
char btAddress[18];
while ((len = read(dd, buf, sizeof(buf))) < 0) {
if (errno == EINTR && signal_received == SIGINT) {
len = 0;
goto done;
}
if (errno == EAGAIN || errno == EINTR)
continue;
goto done;
}
ptr = buf + (1 + HCI_EVENT_HDR_SIZE);
len -= (1 + HCI_EVENT_HDR_SIZE);
meta = (void *) ptr;
if (meta->subevent != 0x02) // must be report type
goto done;
// Overlay report structure
leinfo = (le_advertising_info *) (meta->data + 1);
// Get report count
info("************** BLE Buffer **************");
uint8_t reports_count = meta->data[0];
info("report-count: %d", reports_count);
int i; // Dump LE report data
for (i = 0; i < leinfo->length; i++) {
printf("%02x", leinfo->data[i]);
}
printf("\n");
// Get BT address & type
ba2str(&leinfo->bdaddr, btAddress);
info("BT Address: %s, Type: %s,", btAddress, (leinfo->bdaddr_type == LE_PUBLIC_ADDRESS) ? "public" : "random");
// Get BT Service name
char name[30];
memset(name, 0, sizeof(name));
eir_parse_name(leinfo->data, leinfo->length, name, sizeof(name) - 1);
info("Service name: %s", name);
// Determine Range(RSSI)
int8_t rssi;
rssi = leinfo->data[leinfo->length];
if ((uint8_t) rssi == 0x99 || rssi == 127)
error("RSSI: invalid (0x%2.2x)", (uint8_t) rssi);
else
info("RSSI: %d dBm (0x%2.2x)", rssi, (uint8_t) rssi);
print_eir(leinfo->data, leinfo->length, true);
info("****************************************");
}
done:
setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
if (len < 0)
return -1;
return 0;
}
static void cmd_lescan(int dev_id)
{
int err, dd;
uint8_t own_type = 0x01; // Random
uint8_t scan_type = 0x00; // passive scan - not sending scan responses
uint8_t filter_type = 0;
uint8_t filter_policy = 0x00;
uint16_t interval = htobs(0x0010);
uint16_t window = htobs(0x0010);
uint8_t filter_dup = 0; // not filtering duplicates
info("cmd_lescan");
if (dev_id < 0)
dev_id = hci_get_route(NULL);
dd = hci_open_dev(dev_id);
if (dd < 0) {
perror("Could not open device");
exit(1);
}
err = hci_le_set_scan_parameters(dd, scan_type, interval, window,
own_type, filter_policy, 10000);
if (err < 0) {
perror("Set scan parameters failed");
exit(1);
}
err = hci_le_set_scan_enable(dd, 0x01, filter_dup, 10000);
if (err < 0) {
perror("Enable scan failed");
exit(1);
}
info("LE Scan ...");
err = print_advertising_devices(dd, filter_type);
if (err < 0) {
perror("Could not receive advertising events");
exit(1);
}
err = hci_le_set_scan_enable(dd, 0x00, filter_dup, 10000);
if (err < 0) {
perror("Disable scan failed");
exit(1);
}
hci_close_dev(dd);
}
int main(int argc, char** argv)
{
info("main");
// flush stdout immediately
setvbuf(stdout, NULL, _IONBF, 0);
cmd_lescan(-1);
return 0;
}
I'm able to dump the HCI LE EVENT Report results for an IOS app as follows:
RAW Dump: 02011a1106111111111111111111111111111111110909434253616d706c65
************** BLE Buffer **************
report-count: 1
BT Address: 5E:96:DC:70:18:11
Type: random,
ENTER: eir_parse_name
Service name: CBSample
RSSI: -45 dBm (0xd3)
ENTER: print_eir
BT_EIR_FLAGS
Flags: 0x1a
LE General Discoverable Mode
Simultaneous LE and BR/EDR (Controller)
Simultaneous LE and BR/EDR (Host)
BT_EIR_UUID128_SOME
ENTER: print_uuid128_list
128-bit Service UUIDs (partial): 1 entry
11111111-1111-1111-1111-111111111111
BT_EIR_NAME_COMPLETE
Name (complete): CBSample
****************************************
Unfortunately, the HCI LE Adverting Report only allows for a single 128-BIT BLE Service UUID. Is there a way to customize the report to allow for further information to be gathered without connecting to a device such as iPhone(IOS)?

C++ code to find BSSID OF associated network

Hello I've written the following code which is a part of a project. It is used to find the ESSID of the current associated network.
But it has a flaw: it also the displays the ESSID of the network with which I am not associated i.e. if I try to associate myself with a wireless n/w and if it is unsuccessful i.e. NO DHCP OFFERS ARE RECEIVED, then also it will display the that ESSID with which I have made my attempt.
Could anyone give me an ioctl call to find the BSSID of current associated wireless n/w?. In my opinion it is the only way with which I a can mark b/w associated and non associated.
CODE:-
int main (void)
{
int errno;
struct iwreq wreq;
CStdString result = "None";
int sockfd;
char * id;
char ESSID[100];
memset(&wreq, 0, sizeof(struct iwreq));
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "Cannot open socket \n");
fprintf(stderr, "errno = %d \n", errno);
fprintf(stderr, "Error description is : %s\n",strerror(errno));
return result ;
}
CLog::Log(LOGINFO,"Socket opened successfully");
FILE* fp = fopen("/proc/net/dev", "r");
if (!fp)
{
// TBD: Error
return result;
}
char* line = NULL;
size_t linel = 0;
int n;
char* p;
int linenum = 0;
while (getdelim(&line, &linel, '\n', fp) > 0)
{
// skip first two lines
if (linenum++ < 2)
continue;
p = line;
while (isspace(*p))
++p;
n = strcspn(p, ": \t");
p[n] = 0;
strcpy(wreq.ifr_name, p);
id = new char[IW_ESSID_MAX_SIZE+100];
wreq.u.essid.pointer = id;
wreq.u.essid.length = 100;
if ( ioctl(sockfd,SIOCGIWESSID, &wreq) == -1 ) {
continue;
}
else
{
strcpy(ESSID,id);
return ESSID;
}
free(id);
}
free(line);
fclose(fp);
return result;
}

Reciving UDP packets on iPhone

I'm trying to establish UDP communication between a MAC OS and an iPod through Wi-Fi, at this point I'm able to send packets from the iPod and I can see those packets have the right MAC and ip addresses (I'm using wireshark to monitor the network) but the MAC receives the packets only when the wireshark is on, otherwise recvfrom() returns -1.
When I try to transmit from MAC to iPhone I have the same result, I can see the packets are sent but the iPhone doesn't seem to get them.
I'm using the next code to send:
struct addrinfo hints;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(IP, SERVERPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return 2;
}
while (cond)
sntBytes += sendto(sockfd, message, strlen(message), 0, p->ai_addr, p->ai_addrlen);
return 0;
and this code to receive:
struct addrinfo hints, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use to AF_INET to force IPv4 my IP
if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("listener: socket");
continue;
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("listener: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
addr_len = sizeof their_addr;
fcntl(sockfd, F_SETFL,O_NONBLOCK);
int rcvbuf_size = 128 * 1024; // That's 128Kb of buffer space.
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf_size, sizeof(rcvbuf_size));
printf("listener: waiting to recvfrom...\n");
while (cond)
rcvBytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len);
return 0;
What am I missing?
It would be good to get some more information about the length of data you are sending.
I will assume you are trying to send an ASCII string.
Also, this appears to be either never called or an infinite send loop:
while (cond)
sntBytes += sendto(sockfd, message, strlen(message), 0, p->ai_addr, p->ai_addrlen);
You might want to use code that actually includes some error checking:
Send String
int sendResult = send( connectedSocket, stringBuffer, stringLength, 0 );
if (sendResult == -1) {
perror("Error while trying to send string!");
}
else {
NSLog(#"String '%s' sent successfully", stringBuffer );
}
Receive String
memset( ReceiveBuffer, '\0', sizeof(ReceiveBuffer) );
int receiveResult = recv( connectedSocket, ReceiveBuffer, sizeof(ReceiveBuffer), 0);
if ( receiveResult == -1 ) {
perror("recv");
}
else {
NSLog(#"String received successfully: '%s'", ReceiveBuffer );
}