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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 146 - (hide annotations) (download)
Fri Jun 25 12:00:25 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 13555 byte(s)
* Major changes to server event protocol interface
  on attempt to comply with draft-protocol v.11.

1 capela 105 // 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 capela 125 int i;
42 capela 105 static int iChannel = 0;
43    
44     if (pchBuffer == NULL) {
45     fprintf(stderr, "server_callback: addr=%s port=%d: ",
46     inet_ntoa(pConnect->client.addr.sin_addr),
47     htons(pConnect->client.addr.sin_port));
48     switch (cchBuffer) {
49     case LSCP_CONNECT_OPEN:
50     fprintf(stderr, "New client connection.\n");
51     break;
52     case LSCP_CONNECT_CLOSE:
53     fprintf(stderr, "Connection closed.\n");
54     break;
55     }
56     return ret;
57     }
58    
59     lscp_socket_trace("server_callback", &(pConnect->client.addr), pchBuffer, cchBuffer);
60    
61     lscp_parser_init(&tok, pchBuffer, cchBuffer);
62    
63     if (lscp_parser_test(&tok, "GET")) {
64     if (lscp_parser_test(&tok, "CHANNEL")) {
65     if (lscp_parser_test(&tok, "INFO")) {
66     // Getting sampler channel informations:
67     // GET CHANNEL INFO <sampler-channel>
68     pszResult = "ENGINE_NAME: DummyEngine\r\n"
69     "INSTRUMENT_FILE: DummyInstrument.gig\r\n"
70     "INSTRUMENT_NR: 0\r\n"
71 capela 144 "INSTRUMENT_STATUS: 100\r\n"
72 capela 105 "AUDIO_OUTPUT_DEVICE: 0\r\n"
73     "AUDIO_OUTPUT_CHANNELS: 2\r\n"
74     "AUDIO_OUTPUT_ROUTING: 0,1\r\n"
75     "MIDI_INPUT_DEVICE: 0\r\n"
76     "MIDI_INPUT_PORT: 0\r\n"
77     "MIDI_INPUT_CHANNEL: ALL\r\n"
78     "VOLUME: 0.5\r\n";
79     }
80     else if (lscp_parser_test(&tok, "VOICE_COUNT")) {
81     // Current number of active voices:
82     // GET CHANNEL VOICE_COUNT <sampler-channel>
83     sprintf(szTemp, "%d", rand() % 100);
84     pszResult = szTemp;
85     }
86     else if (lscp_parser_test(&tok, "STREAM_COUNT")) {
87     // Current number of active disk streams:
88     // GET CHANNEL STREAM_COUNT <sampler-channel>
89     pszResult = "3\r\n";
90     }
91     else if (lscp_parser_test(&tok, "BUFFER_FILL")) {
92     if (lscp_parser_test(&tok, "BYTES")) {
93     // Current fill state of disk stream buffers:
94     // GET CHANNEL BUFFER_FILL BYTES <sampler-channel>
95     sprintf(szTemp, "[1]%d,[2]%d,[3]%d\r\n", rand(), rand(), rand());
96     pszResult = szTemp;
97     }
98     else if (lscp_parser_test(&tok, "PERCENTAGE")) {
99     // Current fill state of disk stream buffers:
100     // GET CHANNEL BUFFER_FILL PERCENTAGE <sampler-channel>
101     sprintf(szTemp, "[1]%d%%,[2]%d%%,[3]%d%%\r\n", rand() % 100, rand() % 100, rand() % 100);
102     pszResult = szTemp;
103     }
104     else ret = LSCP_FAILED;
105     }
106     else ret = LSCP_FAILED;
107     }
108     else if (lscp_parser_test(&tok, "CHANNELS")) {
109     // Current number of sampler channels:
110     // GET CHANNELS
111     sprintf(szTemp, "%d", iChannel);
112     pszResult = szTemp;
113     }
114     else if (lscp_parser_test(&tok, "AVAILABLE_AUDIO_OUTPUT_DRIVERS")) {
115     // Getting all available audio output drivers.
116     // GET AVAILABLE_AUDIO_OUTPUT_DRIVERS
117 capela 144 pszResult = "Alsa,Jack,CoreAudio\r\n";
118 capela 105 }
119     else if (lscp_parser_test(&tok, "AVAILABLE_MIDI_INPUT_DRIVERS")) {
120     // Getting all available MIDI input drivers.
121     // GET AVAILABLE_MIDI_INPUT_DRIVERS
122 capela 144 pszResult = "Alsa,MidiShare,CoreMidi\r\n";
123 capela 105 }
124     else if (lscp_parser_test2(&tok, "AUDIO_OUTPUT_DRIVER", "INFO")) {
125     // Getting informations about a specific audio output driver.
126     // GET AUDIO_OUTPUT_DRIVER INFO <audio-output-type>
127     if (lscp_parser_test(&tok, "ALSA")) {
128     pszResult = "DESCRIPTION: 'ALSA PCM'\r\n"
129     "VERSION: '1.0'\r\n"
130     "PARAMETERS: CHANNELS,SAMPLERATE,ACTIVE,CARD\r\n";
131     }
132     else if (lscp_parser_test(&tok, "JACK")) {
133     pszResult = "DESCRIPTION: Jack Audio Connection Kit\r\n"
134     "VERSION: 0.98.1\r\n"
135     "PARAMETERS: CHANNELS,SAMPLERATE,ACTIVE\r\n";
136     }
137     else ret = LSCP_FAILED;
138     }
139     else if (lscp_parser_test2(&tok, "MIDI_INPUT_DRIVER", "INFO")) {
140     // Getting informations about a specific MIDI input driver.
141     // GET MIDI_INPUT_DRIVER INFO <midi-input-type>
142     if (lscp_parser_test(&tok, "ALSA")) {
143     pszResult = "DESCRIPTION: ALSA Sequencer\r\n"
144     "VERSION: 1.0\r\n"
145     "PARAMETERS: PORTS,ACTIVE\r\n";
146     }
147     else ret = LSCP_FAILED;
148     }
149     else if (lscp_parser_test(&tok, "AVAILABLE_ENGINES")) {
150     // Getting all available engines:
151     // GET AVAILABLE_ENGINES
152     pszResult = "Engine1,Engine2,Engine3\r\n";
153     }
154     else if (lscp_parser_test2(&tok, "ENGINE", "INFO")) {
155     // Getting information about an engine.
156     // GET ENGINE INFO <engine-name>
157     pszResult = "DESCRIPTION: DummyEngine\r\n"
158     "VERSION: 1.0\r\n";
159     }
160     else ret = LSCP_FAILED;
161     }
162 capela 125 else if (lscp_parser_test(&tok, "LIST")) {
163     if (lscp_parser_test(&tok, "CHANNELS")) {
164     // Getting all created sampler channel list.
165     // GET CHANNELS
166     if (iChannel > 0) {
167     strcpy(szTemp, "0");
168     for (i = 1; i < iChannel; i++)
169     sprintf(szTemp + strlen(szTemp), ",%d", i);
170     strcat(szTemp, "\r\n");
171     pszResult = szTemp;
172     }
173     else ret = LSCP_FAILED;
174     }
175     else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICES")) {
176     // Getting all created audio output device list.
177     // GET AUDIO_OUTPUT_DEVICES
178     pszResult = "0,1\r\n";
179     }
180     else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICES")) {
181     // Getting all created MID input device list.
182     // GET MIDI_INPUT_DEVICES
183     pszResult = "0\r\n";
184     }
185     else ret = LSCP_FAILED;
186     }
187 capela 105 else if (lscp_parser_test(&tok, "SET")) {
188     if (lscp_parser_test(&tok, "CHANNEL")) {
189     if (lscp_parser_test(&tok, "VOLUME")) {
190     // Setting channel volume:
191     // SET CHANNEL VOLUME <sampler-channel> <volume>
192     }
193     else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_TYPE")) {
194     // Setting audio output type:
195     // SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
196     }
197 capela 125 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_DEVICE")) {
198     // Setting audio output device:
199     // SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
200     }
201 capela 105 else if (lscp_parser_test(&tok, "AUDIO_OUTPUT_CHANNEL")) {
202     // Setting audio output channel:
203 capela 125 // SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-in> <audio-out>
204 capela 105 }
205     else if (lscp_parser_test(&tok, "MIDI_INPUT_TYPE")) {
206     // Setting MIDI input type:
207     // SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
208     }
209 capela 125 else if (lscp_parser_test(&tok, "MIDI_INPUT_DEVICE")) {
210     // Setting MIDI input device:
211     // SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
212     }
213 capela 105 else if (lscp_parser_test(&tok, "MIDI_INPUT_PORT")) {
214     // Setting MIDI input port:
215     // SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
216     }
217     else if (lscp_parser_test(&tok, "MIDI_INPUT_CHANNEL")) {
218     // Setting MIDI input channel:
219     // SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
220     }
221     else ret = LSCP_FAILED;
222     }
223     else ret = LSCP_FAILED;
224     }
225     else if (lscp_parser_test(&tok, "LOAD")) {
226     if (lscp_parser_test(&tok, "ENGINE")) {
227     // Loading a sampler engine:
228     // LOAD ENGINE <engine-name> <sampler-channel>
229     }
230     else if (lscp_parser_test(&tok, "INSTRUMENT")) {
231     // Loading an instrument:
232 capela 144 // LOAD INSTRUMENT [NON_MODAL] <filename> <instr-index> <sampler-channel>
233 capela 105 }
234     else ret = LSCP_FAILED;
235     }
236     else if (lscp_parser_test2(&tok, "ADD", "CHANNEL")) {
237     // Adding a new sampler channel:
238     // ADD CHANNEL
239     sprintf(szTemp, "OK[%d]", iChannel++);
240     pszResult = szTemp;
241     }
242     else if (lscp_parser_test2(&tok, "REMOVE", "CHANNEL")) {
243     // Removing a sampler channel:
244     // REMOVE CHANNEL <sampler-channel>
245     }
246     else if (lscp_parser_test2(&tok, "RESET", "CHANNEL")) {
247     // Resetting a sampler channel:
248     // RESET CHANNEL <sampler-channel>
249     }
250 capela 146 else if (lscp_parser_test(&tok, "SUBSCRIBE")) {
251     // Register frontend for receiving event notification messages:
252     // SUBSCRIBE <event>
253     ret = lscp_server_subscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
254 capela 105 }
255 capela 146 else if (lscp_parser_test(&tok, "UNSUBSCRIBE")) {
256     // Deregister frontend for not receiving event notification messages anymore:
257     // UNSUBSCRIBE <event>
258     ret = lscp_server_unsubscribe(pConnect, lscp_event_from_text(lscp_parser_next(&tok)));
259 capela 105 }
260     else if (lscp_parser_test(&tok, "QUIT")) {
261     // Close client connection:
262     // QUIT
263     lscp_parser_free(&tok);
264     return LSCP_FAILED; // Disconnect.
265     }
266     else ret = LSCP_FAILED;
267    
268     lscp_parser_free(&tok);
269    
270     if (pszResult == NULL)
271     pszResult = (ret == LSCP_OK ? "OK\r\n" : "ERR:1:Failed\r\n");
272    
273     fprintf(stderr, "> %s", pszResult);
274    
275     return lscp_server_result(pConnect, pszResult, strlen(pszResult));
276     }
277    
278     ////////////////////////////////////////////////////////////////////////
279    
280     void server_usage (void)
281     {
282     printf("\n %s %s (Build: %s)\n", lscp_server_package(), lscp_server_version(), lscp_server_build());
283    
284     fputs("\n Available server commands: help, exit, quit, list", stdout);
285     fputs("\n (all else are broadcast verbatim to subscribers)\n\n", stdout);
286     }
287    
288     void server_prompt (void)
289     {
290     fputs("lscp_server> ", stdout);
291     }
292    
293     int main (int argc, char *argv[] )
294     {
295     lscp_server_t *pServer;
296     char szLine[200];
297     int cchLine;
298     lscp_connect_t *p;
299    
300     #if defined(WIN32)
301     if (WSAStartup(MAKEWORD(1, 1), &_wsaData) != 0) {
302     fprintf(stderr, "lscp_server: WSAStartup failed.\n");
303     return -1;
304     }
305     #endif
306    
307     srand(time(NULL));
308    
309     pServer = lscp_server_create(SERVER_PORT, server_callback, NULL);
310     if (pServer == NULL)
311     return -1;
312    
313     server_usage();
314     server_prompt();
315    
316     while (fgets(szLine, sizeof(szLine), stdin)) {
317    
318     cchLine = strlen(szLine);
319     while (cchLine > 0 && (szLine[cchLine - 1] == '\n' || szLine[cchLine - 1] == '\r'))
320     cchLine--;
321     szLine[cchLine] = '\0';
322    
323     if (strcmp(szLine, "exit") == 0 || strcmp(szLine, "quit") == 0)
324     break;
325     else
326     if (strcmp(szLine, "list") == 0) {
327     for (p = pServer->connects.first; p; p = p->next) {
328 capela 146 printf("client: sock=%d addr=%s port=%d events=0x%04x.\n",
329 capela 105 p->client.sock,
330     inet_ntoa(p->client.addr.sin_addr),
331     ntohs(p->client.addr.sin_port),
332 capela 146 (int) p->events
333 capela 105 );
334     }
335     }
336     else
337     if (cchLine > 0 && strcmp(szLine, "help") != 0)
338 capela 146 lscp_server_broadcast(pServer, LSCP_EVENT_MISCELLANEOUS, szLine, strlen(szLine));
339 capela 105 else
340     server_usage();
341    
342     server_prompt();
343     }
344    
345     lscp_server_destroy(pServer);
346    
347     #if defined(WIN32)
348     WSACleanup();
349     #endif
350    
351     return 0;
352     }
353    
354     // end of example_server.c

  ViewVC Help
Powered by ViewVC