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)?
Related
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);
I am using a SD card for data logging. I am using the free fatfs file system from chan and SPI to communicate with the SD card. However I ran into problems when reenserting the card. It no longer works. More specifically the f_mount() function fails in in the disk_initialize() function because it is not recognized as a SDv2 card, altough it is. The first time the function is called (when booting the STM32 controller) this function returns that the card is a SDv2, after taking out the sd card, reinserting and then mounting it again it fails to detect the card.
I have tried to umount it before using f_unmount(), also I cleaned the memory of the FATFs object on the stask.
Before each write I enable powersupply to the sd card and disable it after finish of writing. This works also perfectly fine. as long as I do not reinsert the card. it seems so strange. I also tryied to reinit the SPI before each f_mount. Also does not help.
Following code works fine , but after reinserton of sd card it works no longer:
HAL_SPI_DeInit(&hspi1);
HAL_GPIO_WritePin(__SD_EN_GPIO_Port, __SD_EN_Pin, GPIO_PIN_RESET);
osDelay(10);
while(LightisIniting() == true);
/* reset physical driver */
memset(&SDFatFs, 0, sizeof(FATFS));
f_unmount("0");
osDelay(1);
/* check filenumber */
if ((errorcode = SD_Read_Filenumber()) != NO_ERROR) {
return errorcode;
}
if ((errorcode = SD_Write_Filenumber()) != NO_ERROR) {
return errorcode;
}
static uint8_t SD_Read_Filenumber()
{
char init_data[20];
uint8_t new_file_flag = 0;
uint8_t errorcode = 0;
uint16_t bytesread;
char * pEnd;
errorcode = SD_InitFATFS();
if (errorcode == NO_ERROR) errorcode = SD_File_Open(&SDFileInit, "DATA.INI", FA_OPEN_ALWAYS | FA_READ);
if (errorcode == NO_ERROR) errorcode = SD_File_Read(&SDFileInit, init_data, 20, &bytesread);
if (errorcode == ERROR_SD_READ_DATA_LEN)
{
filenumber = 0; // empty (new) data.ini-file, so set filenumber to 0
new_file_flag = 1;
errorcode = NO_ERROR;
}
else
{
if (errorcode == 0) filenumber = strtol(init_data, &pEnd, 10);
}
if (errorcode == NO_ERROR) errorcode = f_close(&SDFileInit);
if ((errorcode == NO_ERROR) && (new_file_flag)) errorcode = SD_Write_Filenumber();
if (errorcode > 0) filenumber = 0;
return errorcode;
}
static uint8_t SD_Write_Filenumber()
{
char init_data[20];
uint8_t errorcode = 0;
errorcode = SD_InitFATFS();
snprintf(init_data, 10, "%u", filenumber);
if (errorcode == NO_ERROR) errorcode = SD_File_Open(&SDFileInit, "DATA.INI", FA_CREATE_ALWAYS | FA_WRITE);
if (errorcode == NO_ERROR) errorcode = SD_File_Write(&SDFileInit, init_data, strlen(init_data));
if (errorcode == NO_ERROR) errorcode = f_close(&SDFileInit);
return errorcode;
}
int SD_Initialize() {
uint8_t errorcode = 0;
HAL_GPIO_WritePin(__SD_EN_GPIO_Port, __SD_EN_Pin, GPIO_PIN_RESET);
osDelay(1);
while(LightisIniting() == true);
/* check filenumber */
if ((errorcode = SD_Read_Filenumber()) == NO_ERROR) {
filenumber++;
if ((errorcode = SD_Write_Filenumber()) != NO_ERROR) {
return errorcode;
}
}
else {
return errorcode;
}
return 0;
}
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;
}
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 );
}
It seems my questions are strange and i'm not getting enough help but I'm back.
I've another strange question which needs to be solved in emergency.
I'm developing an iPhone app. which uses libssh 2 for commands execution through iPhone over remote host. It's okay and working all methods and commands if i execute them in single.
My problem is,
consider a sequence of commands,
pwd
=> o/p will be /Users/mac01
cd xyz
=> nothing as o/p
pwd
=> o/p will be /Users/mac01/xyz
So, my question is to save the last state of the command which has been executed... but what I'm getting as o/p is
/Users/mac01
after second pwd command execution, which is wrong.
So, could anyone help me out with such type of problems..? Thanks in advance.
I'm using libssh 2.0 library.
The method executing command:
char* cmd_exec(const char *commandline, const char *host, const char *username, const char *password, int port){
int sock, rc, bytecount = 0;
char *cmd_contents;
if(!he)
{
struct sockaddr_in sin;
ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
endif
/* Init and Make Socket Connection */
/* Start Socket Connection */
sock = socket(AF_INET, SOCK_STREAM, 0);
ifndef WIN32
fcntl(sock, F_SETFL, 0);
endif
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
/*sin.sin_addr.s_addr = inet_addr(host);
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { // in case connection failure
fprintf(stderr, "Internet connection is required!\n");
return "NETWORKFAILURE";
}*/
//const char *c = getIPFromHost("pepsi");
//sin.sin_addr.s_addr = inet_addr(c);
/* IP Address Calculation */
he = gethostbyname(host);
if(!he)
return "Invalid hostname";
struct in_addr **addr_list;
addr_list = (struct in_addr **)he->h_addr_list;
//for(int i = 0; addr_list[i] != NULL; i++) {
if(addr_list != NULL){
sin.sin_addr.s_addr = inet_addr(inet_ntoa(*addr_list[0]));
//printf("%s", inet_ntoa(*addr_list[0]));
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { // in case connection failure
fprintf(stderr, "Internet connection is required!\n");
return "NETWORKFAILURE";
}
}
}
/* End Socket Connection */
// Initialize and create Session Instance
if(!session)
{
session = libssh2_session_init();
if ( !session )
{
fprintf( stderr, "Error initializing SSH session\n" );
return "SESSIONFAILURE";
}
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
//libssh2_session_set_blocking(session, 0);
// Session starting
if (libssh2_session_startup(session, sock)) {
fprintf(stderr, "Failure establishing SSH session\n");
return "SESSIONFAILURE";
}
/* Authenticate via password */
if(strlen(password) != 0){
if ( libssh2_userauth_password( session, username, password ) )
{
fprintf( stderr, "Unable to authenticate user [%s]"
"(wrong password specified?)\n", username );
return "AUTHENTICATIONFAILURE";
}
}else{
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
"/home/user/"
".ssh/id_rsa.pub",
"/home/user/"
".ssh/id_rsa",
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n");
return "AUTHENTICATIONFAILURE";
}
}
//libssh2_session_set_blocking(session, 1);
}
// Open a session channel for command execution
if(!channel)
{
channel = libssh2_channel_open_session(session);
if (!channel) {
fprintf(stderr, "Unable to open a session\n");
return "SESSIONFAILURE";
}
// Execute a command through channel
while( (rc = libssh2_channel_shell(channel)) ==
//while( (rc = libssh2_channel_exec(channel, commandline)) ==
LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
if( rc != 0 ) // if command execution failed
{
fprintf(stderr,"Error\n");
return "CMDFAILURE";
}
}
//libssh2_channel_write(channel,commandline,strlen(commandline));
do {
/* write the same data over and over, until error or completion */
rc = libssh2_channel_write(channel, commandline, sizeof(commandline));
if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc);
}
} while (rc == 0);
while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);
/* read channel output */
/* Start channel read */
for( ;; )
{
/* loop until we block */
int rc;
do
{
char buffer[0x4000];
// char *tcontents = (char*)malloc(sizeof(buffer) + sizeof(cmd_contents));
rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
if( rc > 0 )
{
int i;
bytecount += rc;
for( i=0; i < rc; ++i )
fputc( buffer[i], stderr);
if(cmd_contents){
free(cmd_contents);
}
cmd_contents = (char*)malloc(sizeof(buffer) + sizeof(cmd_contents));
strcpy(cmd_contents, buffer);
fprintf(stderr, "\n");
}
else {
//fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
}
}
while( rc > 0 );
/* this is due to blocking that would occur otherwise so we loop on
this condition */
if( rc == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
else
break;
}
/* End channel read */
while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN );
/* closing channel */
int exitcode = 127;
// while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN );
if( rc == 0 )
{
exitcode = libssh2_channel_get_exit_status( channel );
}
//
libssh2_channel_free(channel); // freeup memory
channel = NULL;
/*
libssh2_session_disconnect( session, "" ); // closing session
libssh2_session_free( session ); // free up memory
close( sock ); // closing socket
*/
return cmd_contents;
}
Try this maybe it works... i havent tried it but you can get enough idea and may be the proper solution
libssh2_session_set_blocking(session, 0);
char buffer[0x4000]; rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
for( i=0; i < rc; ++i )
fputc( buffer[i], stderr);
if(cmd_contents)
{
free(cmd_contents);
}
buffer[i] = '\0';
cmd_contents = (char*)malloc(sizeof(buffer) + sizeof(cmd_contents));
strcpy(cmd_contents, buffer);
if( rc == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
hAPPY cODING...
libssh2_session_set_blocking(session, 0);
char buffer[0x4000];
rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
for( i=0; i < rc; ++i )
fputc( buffer[i], stderr);
if(cmd_contents){
free(cmd_contents);
}
buffer[i] = '\0';
cmd_contents = (char*)malloc(sizeof(buffer) + sizeof(cmd_contents));
strcpy(cmd_contents, buffer);
if( rc == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}