-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
X32GetScene.c
167 lines (159 loc) · 4.63 KB
/
X32GetScene.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//
// X32GetScene.c
//
// Created on: Oct 13, 2014
// Author: Patrick-Gilles Maillot
//
// The program connects to X32 (considers connection is always possible, no specific validation)
//
// It then asks for scene data to populate the header for the scene it will create,
// unless -s and -n parameters are provide.
//
// Scene-like data is then read from stdin to extract requests for X32 which will reply
// with /node formatted commands used to fill the newly created scene file.
//
// The created scene file's data is sent to stdout.
//
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#ifdef __WIN32__
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
//
// X32GetScene: An X32 Scene file generator
// Reads stdin getting an X32 Scene file to request the same data from the X32
// Writes the resulting Scene file to stdout
//
#define BSIZE 512
extern int Xsprint(char *bd, int index, char format, void *bs);
int
main(int argc, char **argv)
{
int i, k, read_status;
char l_read[128], c;
struct sockaddr_in Xip;
int fd; // our socket
int recvlen, sendlen;
char b_rec[BSIZE], Xip_str[20], Xport_str[8];
char b_snd[BSIZE];
//
#ifdef __WIN32__
WSADATA wsa;
int Xip_len = sizeof(Xip); // length of addresses
#else
socklen_t Xip_len = sizeof(Xip); // length of addresses
#endif
struct timeval timeout;
fd_set ufds;
//
// initialize communication with X32 server at IP ip and PORT port
// set a default value for server[]; change to match your X32 desk
strcpy (Xip_str, "192.168.0.64");
// port[] = "10023" //change to use a different port
strcpy (Xport_str, "10023");
//
// Manage arguments
recvlen = sendlen = 0;
while ((c = getopt(argc, argv, "i:s:n:h")) != (char)-1) {
switch (c) {
case 'i':
strcpy(Xip_str, optarg );
break;
case 's':
strcpy(b_rec, optarg );
recvlen = 1;
break;
case 'n':
strcpy(b_snd, optarg );
sendlen = 1;
break;
default:
case 'h':
printf("usage: X32GetScene [-i X32 console ipv4 address] [-s scene name][-n note\n");
printf(" default IP is 192.168.0.64\n");
printf("reads from <stdin> scene IDs to request to X32\n");
printf("writes to <stdout> scene IDs and parameters in readable format (identical to *.scn)\n\n");
return(0);
break;
}
}
#ifdef __WIN32__
//Initialize winsock
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
#endif
// Load the X32 address we connect to; we're a client to X32, keep it simple.
// Open a UDP socket
if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("failed to create X32 socket");
return(-1);
}
//
// Construct the server sockaddr_in structure
memset(&Xip, 0, sizeof(Xip)); // Clear struct
Xip.sin_family = AF_INET; // Internet/IP
Xip.sin_addr.s_addr = inet_addr(Xip_str); // IP address
Xip.sin_port = htons(atoi(Xport_str)); // server port
//
// Non blocking mode
timeout.tv_sec = 0;
timeout.tv_usec = 100000; //Set timeout for non blocking recvfrom(): 100ms
//
// All done. Let's send and receive messages
// Establish logical connection with X32 server
//
// Print header
if (!recvlen) {
printf ("Please enter scene name: ");
scanf ("%s", b_rec);
}
if (!sendlen) {
printf ("Please enter note data: ");
scanf ("%s", b_snd);
}
printf ("#2.7# \"%s\" \"%s\" %%000000000 1 X32GetScene V1.5 (c)2014 Patrick-Gilles Maillot\n\n", b_rec, b_snd);
// Open file to interpret from stdin
k = Xsprint (b_snd, 0, 's', "/node");
k = Xsprint (b_snd, k, 's', ",s");
while ((read_status = scanf("%s", l_read)) != EOF) {
if (l_read[0] == '/') {
sendlen = Xsprint(b_snd, k, 's', l_read + 1 );
if (sendto(fd, b_snd, sendlen, 0, (struct sockaddr *)&Xip, Xip_len) < 0) {
perror("coundn't send data with sendto");
return (-1);
}
FD_ZERO (&ufds);
FD_SET (fd, &ufds);
i = select(fd+1, &ufds, NULL, NULL, &timeout);
if (i > 0) {
recvlen = recvfrom(fd, b_rec, BSIZE, 0, (struct sockaddr *)&Xip, &Xip_len);
if (recvlen > 0) {
i = 0;
while((b_rec[i] != '/') && (i < recvlen)) i++;
// print reply to stdout (or attached file); comes with trailing \a and no \0 chars
printf("%s", b_rec + i);
fflush (stdout); // make sure all data is printed out
}
}
} else {
// Decide here if we want to do anything with other command (comments for example)
// Normal commands parameters should be discarded
if (strcmp(l_read, "exit") == 0) break;
}
}
fflush (stdout); // make sure all data is printed out
#ifdef __WIN32__
WSACleanup();
#endif
return(0);
}