/[svn]/liblscp/trunk/examples/example_server.c
ViewVC logotype

Contents of /liblscp/trunk/examples/example_server.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 105 - (show annotations) (download)
Fri Jun 4 14:48:59 2004 UTC (19 years, 10 months ago) by capela
File MIME type: text/plain
File size: 12616 byte(s)
Initial alpha release.

1 // example_server.c
2 //
3 /****************************************************************************
4 Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the 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 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 *****************************************************************************/
21
22 #include "server.h"
23 #include "parser.h"
24
25 #include <time.h>
26
27 #define SERVER_PORT 8888
28
29 #if defined(WIN32)
30 static WSADATA _wsaData;
31 #endif
32
33 ////////////////////////////////////////////////////////////////////////
34
35 lscp_status_t server_callback ( lscp_connect_t *pConnect, const char *pchBuffer, int cchBuffer, void *pvData )
36 {
37 lscp_status_t ret = LSCP_OK;
38 lscp_parser_t tok;
39 const char *pszResult = NULL;
40 char szTemp[256];
41 static int iChannel = 0;
42
43 if (pchBuffer == NULL) {
44 fprintf(stderr, "server_callback: addr=%s port=%d: ",
45 inet_ntoa(pConnect->client.addr.sin_addr),
46 htons(pConnect->client.addr.sin_port));
47 switch (cchBuffer) {
48 case LSCP_CONNECT_OPEN:
49 fprintf(stderr, "New client connection.\n");
50 break;
51 case LSCP_CONNECT_CLOSE:
52 fprintf(stderr, "Connection closed.\n");
53 break;
54 }
55 return ret;
56 }
57
58 lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer);
59
60 lscp_parser_init(&tok, pchBuffer, cchBuffer);
61
62 if (lscp_parser_test(&tok, "GET")) {
63 if (lscp_parser_test(&tok, "CHANNEL")) {
64 if (lscp_parser_test(&tok, "INFO")) {
65 // Getting sampler channel informations:
66 // GET CHANNEL INFO <sampler-channel>
67 pszResult = "ENGINE_NAME: DummyEngine\r\n"
68 "INSTRUMENT_FILE: DummyInstrument.gig\r\n"
69 "INSTRUMENT_NR: 0\r\n"
70 "AUDIO_OUTPUT_DEVICE: 0\r\n"
71 "AUDIO_OUTPUT_CHANNELS: 2\r\n"
72 "AUDIO_OUTPUT_ROUTING: 0,1\r\n"
73 "MIDI_INPUT_DEVICE: 0\r\n"
74 "MIDI_INPUT_PORT: 0\r\n"
75 "MIDI_INPUT_CHANNEL: ALL\r\n"
76 "VOLUME: 0.5\r\n";
77 }
78 else if (lscp_parser_test(&tok, "VOICE_COUNT")) {
79 // Current number of active voices:
80 // GET CHANNEL VOICE_COUNT <sampler-channel>
81 sprintf(szTemp, "%d", rand() % 100);
82 pszResult = szTemp;
83 }
84 else if (lscp_parser_test(&tok, "STREAM_COUNT")) {
85 // Current number of active disk streams:
86 // GET CHANNEL STREAM_COUNT <sampler-channel>
87 pszResult = "3\r\n";
88 }
89 else if (lscp_parser_test(&tok, "BUFFER_FILL")) {
90 if (lscp_parser_test(&tok, "BYTES")) {
91 // Current fill state of disk stream buffers:
92 // GET CHANNEL BUFFER_FILL BYTES <sampler-channel>
93 sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand());
94 pszResult = szTemp;
95 }
96 else if (lscp_parser_test(&tok, "PERCENTAGE")) {
97 // Current fill state of disk stream buffers:
98 // GET CHANNEL BUFFER_FILL PERCENTAGE <sampler-channel>
99 sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100);
100 pszResult = szTemp;
101 }
102 else ret = LSCP_FAILED;
103 }
104 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) {
105 // Getting audio output type:
106 // GET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel>
107 // (unspecified as of draft 04)
108 }
109 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) {
110 // Getting audio output channel:
111 // GET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel>
112 // (unspecified as of draft 04)
113 }
114 else ret = LSCP_FAILED;
115 }
116 else if (lscp_parser_test(&tok, "CHANNELS")) {
117 // Current number of sampler channels:
118 // GET CHANNELS
119 sprintf(szTemp, "%d", iChannel);
120 pszResult = szTemp;
121 }
122 else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) {
123 // Getting all available audio output drivers.
124 // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS
125 pszResult = "ALSA,JACK\r\n";
126 }
127 else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) {
128 // Getting all available MIDI input drivers.
129 // GET AVAILABLE_MIDI_INPUT_DRIVERS
130 pszResult = "ALSA\r\n";
131 }
132 else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) {
133 // Getting informations about a specific audio output driver.
134 // GET AUDIO_OUTPUT_DRIVER INFO <audio-output-type>
135 if (lscp_parser_test(&tok, "ALSA")) {
136 pszResult = "DESCRIPTION: 'ALSA PCM'\r\n"
137 "VERSION: '1.0'\r\n"
138 "PARAMETERS: CHANNELS,SAMPLERATE,ACTIVE,CARD\r\n";
139 }
140 else if (lscp_parser_test(&tok, "JACK")) {
141 pszResult = "DESCRIPTION: Jack Audio Connection Kit\r\n"
142 "VERSION: 0.98.1\r\n"
143 "PARAMETERS: CHANNELS,SAMPLERATE,ACTIVE\r\n";
144 }
145 else ret = LSCP_FAILED;
146 }
147 else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) {
148 // Getting informations about a specific MIDI input driver.
149 // GET MIDI_INPUT_DRIVER INFO <midi-input-type>
150 if (lscp_parser_test(&tok, "ALSA")) {
151 pszResult = "DESCRIPTION: ALSA Sequencer\r\n"
152 "VERSION: 1.0\r\n"
153 "PARAMETERS: PORTS,ACTIVE\r\n";
154 }
155 else ret = LSCP_FAILED;
156 }
157 else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) {
158 // Getting all available engines:
159 // GET AVAILABLE_ENGINES
160 pszResult = "Engine1,Engine2,Engine3\r\n";
161 }
162 else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) {
163 // Getting information about an engine.
164 // GET ENGINE INFO <engine-name>
165 pszResult = "DESCRIPTION: DummyEngine\r\n"
166 "VERSION: 1.0\r\n";
167 }
168 else ret = LSCP_FAILED;
169 }
170 else if (lscp_parser_test(&tok, "SET")) {
171 if (lscp_parser_test(&tok, "CHANNEL")) {
172 if (lscp_parser_test(&tok, "VOLUME")) {
173 // Setting channel volume:
174 // SET CHANNEL VOLUME <sampler-channel> <volume>
175 }
176 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) {
177 // Setting audio output type:
178 // SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
179 }
180 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) {
181 // Setting audio output channel:
182 // SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-channel>
183 }
184 else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) {
185 // Setting MIDI input type:
186 // SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
187 }
188 else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) {
189 // Setting MIDI input port:
190 // SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
191 }
192 else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) {
193 // Setting MIDI input channel:
194 // SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
195 }
196 else ret = LSCP_FAILED;
197 }
198 else ret = LSCP_FAILED;
199 }
200 else if (lscp_parser_test(&tok, "LOAD")) {
201 if (lscp_parser_test(&tok, "ENGINE")) {
202 // Loading a sampler engine:
203 // LOAD ENGINE <engine-name> <sampler-channel>
204 }
205 else if (lscp_parser_test(&tok, "INSTRUMENT")) {
206 // Loading an instrument:
207 // LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
208 }
209 else ret = LSCP_FAILED;
210 }
211 else if (lscp_parser_test2(&tok, "ADD", "CHANNEL")) {
212 // Adding a new sampler channel:
213 // ADD CHANNEL
214 sprintf(szTemp, "OK[%d]", iChannel++);
215 pszResult = szTemp;
216 }
217 else if (lscp_parser_test2(&tok, "REMOVE", "CHANNEL")) {
218 // Removing a sampler channel:
219 // REMOVE CHANNEL <sampler-channel>
220 }
221 else if (lscp_parser_test2(&tok, "RESET", "CHANNEL")) {
222 // Resetting a sampler channel:
223 // RESET CHANNEL <sampler-channel>
224 }
225 else if (lscp_parser_test2(&tok, "SUBSCRIBE", "NOTIFICATION")) {
226 // Register frontend for receiving UDP event messages:
227 // SUBSCRIBE NOTIFICATION <udp-port>
228 ret = lscp_server_subscribe(pConnect, lscp_parser_nextint(&tok));
229 }
230 else if (lscp_parser_test2(&tok, "UNSUBSCRIBE", "NOTIFICATION")) {
231 // Deregister frontend for not receiving UDP event messages anymore:
232 // UNSUBSCRIBE NOTIFICATION <session-id>
233 ret = lscp_server_unsubscribe(pConnect, lscp_parser_next(&tok));
234 }
235 else if (lscp_parser_test(&tok, "QUIT")) {
236 // Close client connection:
237 // QUIT
238 lscp_parser_free(&tok);
239 return LSCP_FAILED; // Disconnect.
240 }
241 else ret = LSCP_FAILED;
242
243 lscp_parser_free(&tok);
244
245 if (pszResult == NULL)
246 pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n");
247
248 fprintf(stderr, "> %s", pszResult);
249
250 return lscp_server_result(pConnect, pszResult, strlen(pszResult));
251 }
252
253 ////////////////////////////////////////////////////////////////////////
254
255 void server_usage (void)
256 {
257 printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build());
258
259 fputs("\n Available server commands: help, exit, quit, list", stdout);
260 fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout);
261 }
262
263 void server_prompt (void)
264 {
265 fputs("lscp_server> ", stdout);
266 }
267
268 int main (int argc, char *argv[] )
269 {
270 lscp_server_t *pServer;
271 char szLine[200];
272 int cchLine;
273 lscp_connect_t *p;
274
275 #if defined(WIN32)
276 if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) {
277 fprintf(stderr, "lscp_server: WSAStartup failed.\n");
278 return -1;
279 }
280 #endif
281
282 srand(time(NULL));
283
284 pServer = lscp_server_create(SERVER_PORT, server_callback, NULL);
285 if (pServer == NULL)
286 return -1;
287
288 server_usage();
289 server_prompt();
290
291 while (fgets(szLine, sizeof(szLine), stdin)) {
292
293 cchLine = strlen(szLine);
294 while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r'))
295 cchLine--;
296 szLine[cchLine] = '\0';
297
298 if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0)
299 break;
300 else
301 if (strcmp(szLine, "list") == 0) {
302 for (p = pServer->connects.first; p; p = p->next) {
303 printf("client: sock=%d addr=%s tcp.port=%d udp.port=%d ping=%d sessid=%s.\n",
304 p->client.sock,
305 inet_ntoa(p->client.addr.sin_addr),
306 ntohs(p->client.addr.sin_port),
307 p->port,
308 p->ping,
309 p->sessid
310 );
311 }
312 }
313 else
314 if (cchLine > 0 && strcmp(szLine, "help") != 0)
315 lscp_server_broadcast(pServer, szLine, strlen(szLine));
316 else
317 server_usage();
318
319 server_prompt();
320 }
321
322 lscp_server_destroy(pServer);
323
324 #if defined(WIN32)
325 WSACleanup();
326 #endif
327
328 return 0;
329 }
330
331 // end of example_server.c

  ViewVC Help
Powered by ViewVC