/[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 105 - (hide annotations) (download)
Fri Jun 4 14:48:59 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 12616 byte(s)
Initial alpha release.

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     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