root/branches/streaming-rework/tests/freebob-server.c

Revision 407, 10.4 kB (checked in by pieterpalmers, 15 years ago)

- Changed the way the device class configure options are handled. Now they are handled in the makefiles instead of the source files. The only source file that still contains the #ifdef's is devicemanager.cpp, to conditionally include the device class include files and to conditionally probe the classes that might be supported.
- added a configure option to disable the compilation of the test programs in tests/
- cleaned up the ADMTP transmit streamprocessor. Now it sends silenced packets when in the disabled state, instead of no-data packets
- added a getNodeID() to ieee1394service
- made comments in ieee1394service.h doxygen compliant

Line 
1 /* freebob-server.c
2  * Copyright (C) 2006,2007 Pieter Palmers
3  *
4  * This file is part of FreeBob.
5 */
6 /* Inspired on:
7 *
8 * avc_vcr.c - An example of an AV/C Tape Recorder target implementation
9 *
10 * Copyright Dan Dennedy <dan@dennedy.org>
11 *
12 * Inspired by virtual_vcr from Bonin Franck <boninf@free.fr>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/poll.h>
32
33 #include <stdio.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <signal.h>
39
40 #include <arpa/inet.h>
41
42 #include <libraw1394/raw1394.h>
43 #include <libraw1394/csr.h>
44 #include <libavc1394/avc1394.h>
45 #include <libavc1394/rom1394.h>
46
47 #include "../libfreebob/freebob.h"
48 #include "../libfreebob/freebob_bounce.h"
49
50 const char not_compatible[] = "\n"
51         "This libraw1394 does not work with your version of Linux. You need a different\n"
52         "version that matches your kernel (see kernel help text for the raw1394 option to\n"
53         "find out which is the correct version).\n";
54
55 const char not_loaded[] = "\n"
56         "This probably means that you don't have raw1394 support in the kernel or that\n"
57         "you haven't loaded the raw1394 module.\n";
58
59
60 static int g_done = 0;
61
62 static void sighandler (int sig)
63 {
64         printf("signal!\n");
65         g_done = 1;
66 }
67
68 /**** subunit handlers ****/
69 int subunit_control( avc1394_cmd_rsp *cr )
70 {
71         switch ( cr->opcode )
72         {
73         default:
74                 fprintf( stderr, "subunit control command 0x%02x non supported\n", cr->opcode );
75                 return 0;
76         }
77         return 1;
78 }
79
80 int subunit_status( avc1394_cmd_rsp *cr )
81 {
82
83         fprintf( stderr, "subunit STATUS\n");
84         char *buffer;
85         switch ( cr->opcode )
86         {
87         case (AVC1394_CMD_INPUT_PLUG_SIGNAL_FORMAT):
88
89                 cr->status = AVC1394_RESP_STABLE;
90                 buffer=(char*)&cr->operand[1];
91                 fprintf( stderr, "subunit AVC1394_COMMAND_INPUT_PLUG_SIGNAL_FORMAT\n");
92                
93                 strncpy(buffer,"TEST123",sizeof(byte_t)*9);
94                 break;
95         default:
96                 fprintf( stderr, "subunit status command 0x%02x not supported\n", cr->opcode );
97                 return 0;
98         }
99         return 1;
100 }
101
102
103 int subunit_inquiry( avc1394_cmd_rsp *cr )
104 {
105         switch ( cr->opcode )
106         {
107         default:
108                 fprintf( stderr, "subunit inquiry command 0x%02x not supported\n", cr->opcode );
109                 return 0;
110         }
111         return 1;
112 }
113
114
115 /**** Unit handlers ****/
116 int unit_control( avc1394_cmd_rsp *cr )
117 {
118         switch ( cr->opcode )
119         {
120         default:
121                 fprintf( stderr, "unit control command 0x%02x not supported\n", cr->opcode );
122                 return 0;
123         }
124         return 1;
125 }
126
127
128 int unit_status( avc1394_cmd_rsp *cr )
129 {
130         cr->operand[1] = 0x00;
131         cr->operand[2] = 0x00;
132         cr->operand[3] = 0x00;
133         cr->operand[4] = 0x00;
134         switch ( cr->opcode )
135         {
136         case AVC1394_CMD_UNIT_INFO:
137                 cr->status = AVC1394_RESP_STABLE;
138                 cr->operand[0] = AVC1394_OPERAND_UNIT_INFO_EXTENSION_CODE;
139                 cr->operand[1] = AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER >> 19;
140                 break;
141         case AVC1394_CMD_SUBUNIT_INFO:
142         {
143                 int page = ( cr->operand[0] >> 4 ) & 7;
144                 if ( page == 0 )
145                 {
146                         cr->status = AVC1394_RESP_STABLE;
147                         cr->operand[0] = (page << 4) | AVC1394_OPERAND_UNIT_INFO_EXTENSION_CODE;
148                         cr->operand[1] = AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER >> 19 << 3;
149                 }
150
151                 else
152                 {
153                         fprintf( stderr, "invalid page %d for subunit\n", page );
154                         return 0;
155                 }
156                 break;
157         }
158         default:
159                 fprintf( stderr, "unit status command 0x%02x not supported\n", cr->opcode );
160                 return 0;
161         }
162         return 1;
163 }
164
165
166 int unit_inquiry( avc1394_cmd_rsp *cr )
167 {
168         switch ( cr->opcode )
169         {
170         case AVC1394_CMD_SUBUNIT_INFO:
171         case AVC1394_CMD_UNIT_INFO:
172                 cr->status = AVC1394_RESP_IMPLEMENTED;
173         default:
174                 fprintf( stderr, "unit inquiry command 0x%02x not supported\n", cr->opcode );
175                 return 0;
176         }
177         return 1;
178 }
179
180
181 /**** primary avc1394 target callback ****/
182 int command_handler( avc1394_cmd_rsp *cr )
183 {
184         switch ( cr->subunit_type )
185         {
186         case AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER:
187                 if ( cr->subunit_id != 0 )
188                 {
189                         fprintf( stderr, "subunit id 0x%02x not supported\n", cr->subunit_id );
190                         return 0;
191                 }
192                 switch ( cr->status )
193                 {
194                 case AVC1394_CTYP_CONTROL:
195                         return subunit_control( cr );
196                         break;
197                 case AVC1394_CTYP_STATUS:
198                         return subunit_status( cr );
199                         break;
200                 case AVC1394_CTYP_GENERAL_INQUIRY:
201                         return subunit_inquiry( cr );
202                         break;
203                 }
204                 break;
205         case AVC1394_SUBUNIT_UNIT:
206                 switch ( cr->status )
207                 {
208                 case AVC1394_CTYP_CONTROL:
209                         return unit_control( cr );
210                         break;
211                 case AVC1394_CTYP_STATUS:
212                         return unit_status( cr );
213                         break;
214                 case AVC1394_CTYP_GENERAL_INQUIRY:
215                         return unit_inquiry( cr );
216                         break;
217                 }
218                 break;
219         default:
220                 fprintf( stderr, "subunit type 0x%02x not supported\n", cr->subunit_type );
221                 return 0;
222         }
223         return 1;
224 }
225
226 struct configrom_backup {
227         quadlet_t rom[0x100];
228         size_t rom_size;
229         unsigned char rom_version;
230        
231 };
232
233 struct configrom_backup save_config_rom(raw1394handle_t handle)
234 {
235         int retval;
236         struct configrom_backup tmp;
237         /* get the current rom image */
238         retval=raw1394_get_config_rom(handle, tmp.rom, 0x100, &tmp.rom_size, &tmp.rom_version);
239 //      tmp.rom_size=rom1394_get_size(tmp.rom);
240         printf("save_config_rom get_config_rom returned %d, romsize %d, rom_version %d:\n",retval,tmp.rom_size,tmp.rom_version);
241
242         return tmp;
243 }
244
245 int restore_config_rom(raw1394handle_t handle, struct configrom_backup old)
246 {
247         int retval,i ;
248
249         quadlet_t current_rom[0x100];
250         size_t current_rom_size;
251         unsigned char current_rom_version;
252
253         retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
254         printf("restore_config_rom get_config_rom returned %d, romsize %d, rom_version %d:\n",retval,current_rom_size,current_rom_version);
255
256         printf("restore_config_rom restoring to romsize %d, rom_version %d:\n",old.rom_size,old.rom_version);
257
258         retval = raw1394_update_config_rom(handle, old.rom, old.rom_size, current_rom_version);
259         printf("restore_config_rom update_config_rom returned %d\n",retval);
260
261         /* get the current rom image */
262         retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
263         current_rom_size = rom1394_get_size(current_rom);
264         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,current_rom_size,current_rom_version);
265         for (i = 0; i < current_rom_size; i++)
266         {
267                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
268                 printf(" %08x", ntohl(current_rom[i]));
269         }
270         printf("\n");
271
272         return retval;
273 }
274
275 int init_config_rom(raw1394handle_t handle)
276 {
277         int retval, i;
278         quadlet_t rom[0x100];
279         size_t rom_size;
280         unsigned char rom_version;
281         rom1394_directory dir;
282         char *leaf;
283        
284         /* get the current rom image */
285         retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
286         rom_size = rom1394_get_size(rom);
287         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
288         for (i = 0; i < rom_size; i++)
289         {
290                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
291                 printf(" %08x", ntohl(rom[i]));
292         }
293         printf("\n");
294        
295         /* get the local directory */
296         rom1394_get_directory( handle, raw1394_get_local_id(handle) & 0x3f, &dir);
297        
298         /* change the vendor description for kicks */
299         i = strlen(dir.textual_leafs[0]);
300         strncpy(dir.textual_leafs[0], FREEBOB_BOUNCE_SERVER_VENDORNAME "                                          ", i);
301        
302         dir.vendor_id=FREEBOB_BOUNCE_SERVER_VENDORID;
303         dir.model_id=FREEBOB_BOUNCE_SERVER_MODELID;
304        
305         /* update the rom */
306         retval = rom1394_set_directory(rom, &dir);
307         printf("rom1394_set_directory returned %d, romsize %d:",retval,rom_size);
308         for (i = 0; i < rom_size; i++)
309         {
310                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
311                 printf(" %08x", ntohl(rom[i]));
312         }
313         printf("\n");
314        
315         /* free the allocated mem for the textual leaves */
316         rom1394_free_directory( &dir);
317        
318         /* add an AV/C unit directory */
319         dir.unit_spec_id    = FREEBOB_BOUNCE_SERVER_SPECID;
320         dir.unit_sw_version = 0x00010001;
321         leaf = FREEBOB_BOUNCE_SERVER_MODELNAME;
322         dir.nr_textual_leafs = 1;
323         dir.textual_leafs = &leaf;
324        
325         /* manipulate the rom */
326         retval = rom1394_add_unit( rom, &dir);
327        
328         /* get the computed size of the rom image */
329         rom_size = rom1394_get_size(rom);
330        
331         printf("rom1394_add_unit_directory returned %d, romsize %d:",retval,rom_size);
332         for (i = 0; i < rom_size; i++)
333         {
334                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
335                 printf(" %08x", ntohl(rom[i]));
336         }
337         printf("\n");
338        
339         /* convert computed rom size from quadlets to bytes before update */
340         rom_size *= sizeof(quadlet_t);
341         retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
342         printf("update_config_rom returned %d\n",retval);
343        
344         retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
345         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
346         for (i = 0; i < rom_size; i++)
347         {
348                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
349                 printf(" %08x", ntohl(rom[i]));
350         }
351         printf("\n");
352        
353 //      printf("You need to reload your ieee1394 modules to reset the rom.\n");
354        
355         return 0;
356 }
357
358
359 int main( int argc, char **argv )
360 {
361         raw1394handle_t handle;
362     int p=0;
363    
364         signal (SIGINT, sighandler);
365         signal (SIGPIPE, sighandler);
366
367         handle = raw1394_new_handle();
368
369     if (argc==2) p=atoi(argv[1]);
370
371         if ( !handle )
372         {
373                 if ( !errno )
374                 {
375                         printf( not_compatible );
376                 }
377                 else
378                 {
379                         perror( "couldn't get handle" );
380                         printf( not_loaded );
381                 }
382                 exit( EXIT_FAILURE );
383         }
384
385         if ( raw1394_set_port( handle, p ) < 0 )
386         {
387                 perror( "couldn't set port" );
388                 exit( EXIT_FAILURE );
389         } else {
390            printf("Using port %d\n",p);
391         }
392
393         struct configrom_backup cfgrom_backup;
394         cfgrom_backup=save_config_rom( handle );
395
396         if ( init_config_rom( handle ) < 0 )
397         {
398                 perror( "couldn't init config rom!" );
399                 exit( EXIT_FAILURE );
400         }
401
402
403         avc1394_init_target( handle, command_handler );
404        
405         printf( "Starting AV/C target; press Ctrl+C to quit...\n" );
406         struct pollfd pfd = {
407                 fd: raw1394_get_fd (handle),
408                 events: POLLIN | POLLPRI,
409                 revents: 0
410         };
411         int result = 0;
412        
413
414         do {
415                 if (poll (&pfd, 1, 100) > 0 && (pfd.revents & POLLIN))
416                 result = raw1394_loop_iterate (handle);
417                
418         } while (g_done == 0 && result == 0);
419        
420         avc1394_close_target( handle );
421        
422         restore_config_rom( handle, cfgrom_backup);
423
424         printf( "Bye...\n" );
425         exit( EXIT_SUCCESS );
426 }
Note: See TracBrowser for help on using the browser.