CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

oscsend.c
Go to the documentation of this file.
1 /*
2 * oscsend - Send OpenSound Control message.
3 *
4 * Copyright (C) 2008 Kentaro Fukuchi <fukuchi@megaui.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * TODO:
21 * - support binary blob.
22 * - support TimeTag.
23 * - receive replies.
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <math.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <config.h>
32 #include <limits.h>
33 #include <lo/lo.h>
34
35 void usage(void)
36 {
37 printf("oscsend version %s\n"
38 "Copyright (C) 2008 Kentaro Fukuchi\n\n"
39 "Usage: oscsend hostname port address types values...\n"
40 "Send OpenSound Control message via UDP.\n\n"
41 "Description\n"
42 "hostname: specifies the remote host's name.\n"
43 "port : specifies the port number to connect to the remote host.\n"
44 "address : the OSC address where the message to be sent.\n"
45 "types : specifies the types of the following values.\n",
46 VERSION);
47 printf(" %c - 32bit integer\n", LO_INT32);
48 printf(" %c - 64bit integer\n", LO_INT64);
49 printf(" %c - 32bit floating point number\n", LO_FLOAT);
50 printf(" %c - 64bit (double) floating point number\n", LO_DOUBLE);
51 printf(" %c - string\n", LO_STRING);
52 printf(" %c - symbol\n", LO_SYMBOL);
53 printf(" %c - char\n", LO_CHAR);
54 printf(" %c - 4 byte midi packet (8 digits hexadecimal)\n", LO_MIDI);
55 printf(" %c - TRUE (no value required)\n", LO_TRUE);
56 printf(" %c - FALSE (no value required)\n", LO_FALSE);
57 printf(" %c - NIL (no value required)\n", LO_NIL);
58 printf(" %c - INFINITUM (no value required)\n", LO_INFINITUM);
59 printf("values : space separated values.\n\n"
60 "Example\n"
61 "$ oscsend localhost 7777 /sample/address %c%c%c%c 1 3.14 hello\n",
62 LO_INT32, LO_TRUE, LO_FLOAT, LO_STRING);
63 }
64
65 lo_message create_message(char **argv)
66 {
67 /* Note:
68 * argv[1] <- hostname
69 * argv[2] <- port
70 * argv[3] <- OSC address
71 * argv[4] <- types
72 * argv[5..] <- values
73 */
74 int i, argi;
75 lo_message message;
76 const char *types, *arg;
77 int values;
78
79 message = lo_message_new();
80 if(argv[4] == NULL) {
81 /* empty message is allowed. */
82 values = 0;
83 } else {
84 types = argv[4];
85 values = strlen(types);
86 }
87
88 argi = 5;
89 for(i=0; i<values; i++) {
90 arg = argv[argi];
91 if(arg == NULL) {
92 fprintf(stderr, "Value #%d is not given.\n", i + 1);
93 goto EXIT;
94 }
95 switch(types[i]) {
96 case LO_INT32:
97 {
98 char *endp;
99 int64_t v;
100
101 v = strtol(arg, &endp, 10);
102 if(*endp != '\0') {
103 fprintf(stderr, "An invalid value was given: '%s'\n", arg);
104 goto EXIT;
105 }
106 if((v == LONG_MAX || v == LONG_MIN) && errno == ERANGE) {
107 fprintf(stderr, "Value out of range: '%s'\n", arg);
108 goto EXIT;
109 }
110 if(v > INT_MAX || v < INT_MIN) {
111 fprintf(stderr, "Value out of range: '%s'\n", arg);
112 goto EXIT;
113 }
114 lo_message_add_int32(message, (int32_t)v);
115 argi++;
116 break;
117 }
118 case LO_INT64:
119 {
120 char *endp;
121 int64_t v;
122
123 v = strtoll(arg, &endp, 10);
124 if(*endp != '\0') {
125 fprintf(stderr, "An invalid value was given: '%s'\n", arg);
126 goto EXIT;
127 }
128 if((v == LONG_MAX || v == LONG_MIN) && errno == ERANGE) {
129 fprintf(stderr, "Value out of range: '%s'\n", arg);
130 goto EXIT;
131 }
132 lo_message_add_int64(message, v);
133 argi++;
134 break;
135 }
136 case LO_FLOAT:
137 {
138 char *endp;
139 float v;
140
141 #ifdef __USE_ISOC99
142 v = strtof(arg, &endp);
143 #else
144 v = (float)strtod(arg, &endp);
145 #endif /* __USE_ISOC99 */
146 if(*endp != '\0') {
147 fprintf(stderr, "An invalid value was given: '%s'\n", arg);
148 goto EXIT;
149 }
150 lo_message_add_float(message, v);
151 argi++;
152 break;
153 }
154 case LO_DOUBLE:
155 {
156 char *endp;
157 double v;
158
159 v = strtod(arg, &endp);
160 if(*endp != '\0') {
161 perror(NULL);
162 fprintf(stderr, "An invalid value was given: '%s'\n", arg);
163 goto EXIT;
164 }
165 lo_message_add_double(message, v);
166 argi++;
167 break;
168 }
169 case LO_STRING:
170 lo_message_add_string(message, arg);
171 argi++;
172 break;
173 case LO_SYMBOL:
174 lo_message_add_symbol(message, arg);
175 argi++;
176 break;
177 case LO_CHAR:
178 lo_message_add_char(message, arg[0]);
179 argi++;
180 break;
181 case LO_MIDI:
182 {
183 unsigned int midi;
184 uint8_t packet[4];
185 int ret;
186
187 ret = sscanf(arg, "%08x", &midi);
188 if(ret != 1) {
189 fprintf(stderr, "An invalid hexadecimal value was given: '%s'\n", arg);
190 goto EXIT;
191 }
192 packet[0] = (midi>>24) & 0xff;
193 packet[1] = (midi>>16) & 0xff;
194 packet[2] = (midi>> 8) & 0xff;
195 packet[3] = midi & 0xff;
196 lo_message_add_midi(message, packet);
197 argi++;
198 break;
199 }
200 case LO_TRUE:
201 lo_message_add_true(message);
202 break;
203 case LO_FALSE:
204 lo_message_add_false(message);
205 break;
206 case LO_NIL:
207 lo_message_add_nil(message);
208 break;
209 case LO_INFINITUM:
210 lo_message_add_infinitum(message);
211 break;
212 default:
213 fprintf(stderr, "Type '%c' is not supported or invalid.\n", types[i]);
214 goto EXIT;
215 break;
216 }
217 }
218
219 return message;
220 EXIT:
221 lo_message_free(message);
222 return NULL;
223 }
224
225 int main(int argc, char **argv)
226 {
227 lo_address target;
228 lo_message message;
229 int ret;
230
231 if(argc < 4) {
232 usage();
233 exit(1);
234 }
235
236 if(argv[1] == NULL) {
237 fprintf(stderr, "No hostname is given.\n");
238 exit(1);
239 }
240 if(argv[2] == NULL) {
241 fprintf(stderr, "No port number is given.\n");
242 exit(1);
243 }
244
245 target = lo_address_new(argv[1], argv[2]);
246 if(target == NULL) {
247 fprintf(stderr, "Failed to open %s:%s\n", argv[1], argv[2]);
248 exit(1);
249 }
250
251 if(argv[3] == NULL) {
252 fprintf(stderr, "No path is given.\n");
253 exit(1);
254 }
255
256 message = create_message(argv);
257 if(message == NULL) {
258 fprintf(stderr, "Failed to create OSC message.\n");
259 exit(1);
260 }
261
262 ret = lo_send_message(target, argv[3], message);
263 if(ret == -1) {
264 fprintf(stderr, "An error occured: %s\n", lo_address_errstr(target));
265 exit(1);
266 }
267
268 return 0;
269 }