how to perform ssdp communicationbetween upnp devices - udp
i am trying to implement the upnp level communication between the devices .. but facing problem in getting the response message .and more over on sending the ssdp:discovery multicast not able to recieve the messages from the devices ... please guide me through i am completely newto this topic
pre-requisite done by me :
1.able to send the M-Search ..and notify message on the network .. and have confirmed via wireshark
2.gone through the upnp architecture related pdf
response got in wireshark :
when ever i am sending the message i am getting the icmp error message that destination is not reachable ..
< client side code > is the first one and second one is the for time being i am just sending up the data on local host
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define SRV_IP "127.0.0.1"
/* diep(), #includes and #defines like in the server */
#define BUFLEN 512
#define NPACK 10
#define PORT 1900
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
for (i=0; i<NPACK; i++) {
printf("Sending packet %d\n", i);
sprintf(buf, "\n");
if (sendto(s, buf, BUFLEN, 0, &si_other, slen)==-1)
diep("sendto()");
}
close(s);
return 0;
}
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFLEN 512
#define NPACK 10
#define PORT 1900
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, &si_me, sizeof(si_me))==-1)
diep("bind");
for (i=0; i<NPACK; i++) {
if (recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)==-1)
diep("recvfrom()");
printf("Received packet from %s:%d\nData: %s\n\n",
inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
}
close(s);
return 0;
}
The individual lines in you M-SEARCH need to have "\r\n" at the end of each line, not just a "\n". Your system may just be sending "\n" across the wire. Check the bytes you're sending for a 13 followed by a 10. That's "\r\n".
Related
How can I modify my code to read from a file input in client and then communicate it to a server?
Code: //server.c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <WinSock2.h> #include <Windows.h> #define SCK_VERSION 0x0202 int main() { //declare sockets first SOCKET ConSock; // used for connection, hence the name SOCKET ListenSock; // used for listening from the server SOCKADDR_IN address; //socket address int addrsize = sizeof(address); long ok; char MESSAGE[200]; char reply[200]; WSADATA WSD; WORD DllVersion; DllVersion = MAKEWORD(2,1); ok = WSAStartup(DllVersion, &WSD); //start creating our sockets ConSock = socket(AF_INET, SOCK_STREAM, NULL); address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_family = AF_INET; address.sin_port = htons(10103); ListenSock = socket(AF_INET, SOCK_STREAM, NULL); bind(ListenSock, (SOCKADDR*)&address, sizeof(address)); listen(ListenSock, SOMAXCONN); printf("Server waiting for connections\n\n"); for(;;){ if (ConSock = accept(ListenSock, (SOCKADDR*)&address, &addrsize)) { ok = recv(ConSock, MESSAGE, sizeof(MESSAGE),NULL); printf("\nClient says:\t %s", MESSAGE); printf("\nEnter reply:\t"); gets(reply); ok = send(ConSock,reply,200,NULL); } } } //client.c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <WinSock2.h> #include <Windows.h> #define SCK_VERSION 0x0202 int main() { SOCKET sock; SOCKADDR_IN address; long ok; char MESSAGE[200]; char reply[200]; WSADATA WSD; WORD DllVersion; DllVersion = MAKEWORD(2,1); ok = WSAStartup(DllVersion, &WSD); address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_family = AF_INET; address.sin_port = htons(10103); for(;;) { sock = socket(AF_INET,SOCK_STREAM,NULL); connect(sock, (SOCKADDR*)&address, sizeof(address)); printf("\nEnter Message:\t"); gets(MESSAGE); ok = send(sock,MESSAGE,200,NULL); ok = recv(sock,reply,sizeof(reply),NULL); printf("\nServer says:\t %s",reply); } } //makefile server: g++ server.c -o server client: g++ client.c -o client clean: rm server rm client all: server client This runs with -lwsock32 and it does a good job, but I need to adjust it now to comunicate some data from a file, the data is mostly values of voltages, currents, active reactive power, etc. I have been trying for quite some time and I cannot seem to adjust it. If you can rewrite it in terms of the client communicating the values(that are stored in a file) to the server, that will be great. Any help is greatly appreciated, as I am not being succesful currently.
Find CPU times and system times of process in linux
I have a main program that creates two children and each children calls execlv. At the end of the program how do I calculate the CPU times and system times of the parent and two process? #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> int main() { pid_t pid1,pid2,wid; // variable for parent and two children char *my_args[3]; // strign array for containing the arguments for executing sigShooter1 // int aInt = 368; // char str[15]; // strign to contain the pids of children when passing as command line arguments pid1 = fork(); if (pid1 < 0) { fprintf(stderr, ": fork failed: %s\n", strerror(errno)); exit(1); } if(pid1 == 0) { my_args[0] = "sigperf1"; my_args[1] = "0"; my_args[2] = NULL; execv("sigshooter1",my_args); fprintf(stderr,"sigshooter1 cannot be executed by first child..."); exit(-1); } pid2 = fork(); if(pid2 < 0) { fprintf(stderr, ": fork failed: %s\n", strerror(errno)); exit(1); } if(pid2 == 0) { sprintf(str, "%d", pid1); my_args[0] = "sigperf1"; my_args[1] = str; my_args[2] = NULL; // printf("this is converted = %s\n",my_args[1]); //sleep(1); execv("sigshooter1",my_args); fprintf(stderr,"sigshooter1 cannot be executed by second child..."); exit(-1); } wid = wait(NULL); }
You'll need a profiler for that. For starters, you can run perf stat ./a.out to get the total CPU time of all three processes, and perf stat -i ./a.out to get the CPU time of parent process only. If you need something more detailed, take a look at more serious tools like valgrind or gprof.
configuration of adafruit ultimate gps from raspberry pi does not work
I connected my ultimate gps breakout to my raspberry pi using the USB to TTL serial cable. Using C code I can easily connect to and read NMEA sentences from the GPS. But when I write configuration commands such as PMTK220 to set the update rate, they are ignored. I should get back a PMTK_ACK reporting success or failure, but it is not forthcoming. The problem also occurs when I use terminal windows. ie. I run: while (true) do cat -A /dev/ttyUSB0 ; done in one terminal, and get a stream of $GPGGA, $GPGSA, $GPRMC etc messages. In another terminal I run: echo "$PMTK220,200*2C\r\n" > /dev/ttyUSB0 The NMEA messages continue but there is no PMTK001 coming back. Any ideas?
Ok, here's some code (inspired by gpsd source) that demonstrates sending a configuration message and getting an acknowledgement: #define _BSD_SOURCE #include <stdio.h> #include <stdarg.h> #include <sys/ioctl.h> #include <termios.h> #include <fcntl.h> #include <unistd.h> #include <assert.h> #include <semaphore.h> #include <string.h> #ifndef CRTSCTS # ifdef CNEW_RTSCTS # define CRTSCTS CNEW_RTSCTS # else # define CRTSCTS 0 # endif /* CNEW_RTSCTS */ #endif /* !CRTSCTS */ int main (int argc, char **argv) { int const baudr = B9600, mode = O_RDWR | O_NONBLOCK | O_NOCTTY; int const fd = open("/dev/ttyUSB0", mode); assert (fd != -1); ioctl(fd, (unsigned long)TIOCEXCL); struct termios ttyOld, ttyNew; assert(tcgetattr(fd, &ttyOld) != -1); ttyNew = ttyOld; ttyNew.c_cflag &= ~(CSIZE | PARENB | PARODD | CRTSCTS | CSTOPB); ttyNew.c_cflag |= CREAD | CLOCAL | CS8; ttyNew.c_iflag = ttyNew.c_oflag = 0; ttyNew.c_lflag = ICANON; cfsetispeed(&ttyNew, baudr); cfsetospeed(&ttyNew, baudr); assert(tcsetattr(fd, TCSANOW, &ttyNew) != -1); tcflush(fd, TCIOFLUSH); usleep(200000); tcflush(fd, TCIOFLUSH); int const oldfl = fcntl(fd, F_GETFL); assert (oldfl != -1); fcntl(fd, F_SETFL, oldfl & ~O_NONBLOCK); tcdrain(fd); printf("port opened baudr=%d mode=%d i=%d o=%d c=%d l=%d fl=%d\n", baudr, mode, ttyNew.c_iflag, ttyNew.c_oflag, ttyNew.c_cflag, ttyNew.c_lflag, oldfl); unsigned char buf[2048]; int count = 0; while(++count < 20) { if (count == 4) { char const *const cmd = "$PMTK220,200*2C\r\n"; int const n = strlen(cmd); assert(write(fd, cmd, n) == n); tcdrain(fd); printf("wrote command %d: %s\n", n, cmd); } int const n = read(fd, buf, sizeof(buf)); buf[(n >= sizeof(buf)) ? (sizeof(buf) - 1) : n] = 0; printf(buf); } tcsetattr(fd, TCSANOW, &ttyOld); close(fd); } with results: pi#pi01 ~/c $ ./test port opened baudr=13 mode=2306 i=0 o=0 c=3261 l=2 fl=2050 $GPGGA,175748.089,,,,,0,00,,,M,,M,,*71 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPRMC,175748.089,V,,,,,0.00,0.00,260715,,,N*43 wrote command 17: $PMTK220,200*2C $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32 $PMTK001,220,2*31 $GPGGA,175749.089,,,,,0,00,,,M,,M,,*70 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,1,1,01,11,,,31*7A $GPRMC,175749.089,V,,,,,0.00,0.00,260715,,,N*42 $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32 $GPGGA,175750.089,,,,,0,00,,,M,,M,,*78 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPRMC,175750.089,V,,,,,0.00,0.00,260715,,,N*4A $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32 $GPGGA,175751.089,,,,,0,00,,,M,,M,,*79 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPRMC,175751.089,V,,,,,0.00,0.00,260715,,,N*4B $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32 $GPGGA,175752.089,,,,,0,00,,,M,,M,,*7A pi#pi01 ~/c $
getaddrinfo on raspbian returns only loopback IP, same code on OS X multiple
I have a short test program to fetch the IP address of the local machine. On Raspbian, only the loopback address is returned, while the same code on OS X return both normal and loopback IPs. The code is #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <errno.h> using namespace std; int main (int argc, char * const argv[]) { char hostname[128]; int result = gethostname(hostname, 127); if (result != 0) { cout << "FATAL: gethostname failed: " << result << errno; return -1; } cout << "Host name is " << hostname << endl; struct addrinfo hints, *res; int errcode; char addrstr[100]; void *ptr; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags |= AI_CANONNAME; errcode = getaddrinfo(hostname, NULL, &hints, &res); if (errcode != 0) { perror("getaddrinfo"); return -1; } while(res) { inet_ntop(res->ai_family, res->ai_addr->sa_data, addrstr, 100); switch(res->ai_family) { case AF_INET: ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; break; case AF_INET6: ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; break; default: cout << "Unknown family" << endl; } inet_ntop(res->ai_family, ptr, addrstr, 100); printf("IPV%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname); res = res->ai_next; } return 0; } On OS X I get: [Coyote]collector$ ./quick Host name is Coyote.local IPV4 address: 192.168.1.108 (coyote.local) IPV6 address: fe80::223:dfff:fea0:a230 (coyote.local) But on Raspbian I only get: pi:~$ ./quick Host name is pi IPV4 address: 127.0.1.1 (pi) yet pi:~$ ifconfig eth0 Link encap:Ethernet HWaddr b8:27:eb:62:15:fc inet addr:192.168.1.162 Bcast:192.168.1.255 Mask:255.255.255.0 [...] What do I need to do on Raspbian to get the correct result?
This is probably due to the contents of your /etc/hosts file. If your goal is to obtain the ip addresses of the system, consider using getifaddrs instead. It's of BSD origin, but works on Linux as well. If you want for sure to know which address will be used when you connect somewhere, the best way to do it than to connect and then obtain the address using getsockname. The other option would be to read the routing tables. Also, getnameinfo is usually a better choice than inet_ntop.
How to print HFS Volume header
Any one please give code snippet for how to print volume header of HFS+ disk.
I’ve written a small program (based on hfs-183.1) that prints some of the information declared in struct HFSPlusVolumeHeader. The program must be run as root — for instance, via sudo(8): #include <fcntl.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <hfs/hfs_format.h> #include <libkern/OSByteOrder.h> int main(void) { int fd; struct stat stat_buf; struct HFSPlusVolumeHeader vheader; const char *vname = "/dev/rdisk0s2"; if (lstat(vname, &stat_buf) == -1) { fprintf(stderr, "Couldn't stat %s\n", vname); perror(NULL); exit(1); } if ((stat_buf.st_mode & S_IFMT) != S_IFCHR) { fprintf(stderr, "%s is not a raw char device\n", vname); perror(NULL); exit(2); } fd = open(vname, O_RDONLY); if (fd == -1) { fprintf(stderr, "%s couldn't be opened for reading\n", vname); perror(NULL); exit(3); } // The volume header starts at offset 1024 if (pread(fd, &vheader, sizeof vheader, 1024) != sizeof vheader) { fprintf(stderr, "couldn't read %s's volume header\n", vname); perror(NULL); exit(4); } printf("fileCount = %u\n" "folderCount = %u\n" "blockSize = %u\n" "totalBlocks = %u\n" "freeBlocks = %u\n", OSSwapBigToHostInt32(vheader.fileCount), OSSwapBigToHostInt32(vheader.folderCount), OSSwapBigToHostInt32(vheader.blockSize), OSSwapBigToHostInt32(vheader.totalBlocks), OSSwapBigToHostInt32(vheader.freeBlocks)); close(fd); return 0; } The header file <hfs/hfs_format.h> declares struct HFSPlusVolumeHeader. See this file for the complete list of fields inside a HFS+ volume header.
The system call getattrlist() might give you the information you need.