root/trunk/libfreebob/tests/freebob-server.c

Revision 240, 10.4 kB (checked in by pieterpalmers, 16 years ago)

- small update to the freebob-server program

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