root/branches/libfreebob-motu/tests/freebob-server.c

Revision 197, 10.1 kB (checked in by pieterpalmers, 16 years ago)

- implemented first steps of MOTU device discovery

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         switch ( cr->opcode )
64         {
65         default:
66                 fprintf( stderr, "subunit control command 0x%02x non supported\n", cr->opcode );
67                 return 0;
68         }
69         return 1;
70 }
71
72 int subunit_status( avc1394_cmd_rsp *cr )
73 {
74
75         fprintf( stderr, "subunit STATUS\n");
76         char *buffer;
77         switch ( cr->opcode )
78         {
79         case (AVC1394_CMD_INPUT_PLUG_SIGNAL_FORMAT):
80
81                 cr->status = AVC1394_RESP_STABLE;
82                 buffer=(char*)&cr->operand[1];
83                 fprintf( stderr, "subunit AVC1394_COMMAND_INPUT_PLUG_SIGNAL_FORMAT\n");
84                
85                 strncpy(buffer,"TEST123",sizeof(byte_t)*9);
86                 break;
87         default:
88                 fprintf( stderr, "subunit status command 0x%02x not supported\n", cr->opcode );
89                 return 0;
90         }
91         return 1;
92 }
93
94
95 int subunit_inquiry( avc1394_cmd_rsp *cr )
96 {
97         switch ( cr->opcode )
98         {
99         default:
100                 fprintf( stderr, "subunit inquiry command 0x%02x not supported\n", cr->opcode );
101                 return 0;
102         }
103         return 1;
104 }
105
106
107 /**** Unit handlers ****/
108 int unit_control( avc1394_cmd_rsp *cr )
109 {
110         switch ( cr->opcode )
111         {
112         default:
113                 fprintf( stderr, "unit control command 0x%02x not supported\n", cr->opcode );
114                 return 0;
115         }
116         return 1;
117 }
118
119
120 int unit_status( avc1394_cmd_rsp *cr )
121 {
122         cr->operand[1] = 0x00;
123         cr->operand[2] = 0x00;
124         cr->operand[3] = 0x00;
125         cr->operand[4] = 0x00;
126         switch ( cr->opcode )
127         {
128         case AVC1394_CMD_UNIT_INFO:
129                 cr->status = AVC1394_RESP_STABLE;
130                 cr->operand[0] = AVC1394_OPERAND_UNIT_INFO_EXTENSION_CODE;
131                 cr->operand[1] = AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER >> 19;
132                 break;
133         case AVC1394_CMD_SUBUNIT_INFO:
134         {
135                 int page = ( cr->operand[0] >> 4 ) & 7;
136                 if ( page == 0 )
137                 {
138                         cr->status = AVC1394_RESP_STABLE;
139                         cr->operand[0] = (page << 4) | AVC1394_OPERAND_UNIT_INFO_EXTENSION_CODE;
140                         cr->operand[1] = AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER >> 19 << 3;
141                 }
142
143                 else
144                 {
145                         fprintf( stderr, "invalid page %d for subunit\n", page );
146                         return 0;
147                 }
148                 break;
149         }
150         default:
151                 fprintf( stderr, "unit status command 0x%02x not supported\n", cr->opcode );
152                 return 0;
153         }
154         return 1;
155 }
156
157
158 int unit_inquiry( avc1394_cmd_rsp *cr )
159 {
160         switch ( cr->opcode )
161         {
162         case AVC1394_CMD_SUBUNIT_INFO:
163         case AVC1394_CMD_UNIT_INFO:
164                 cr->status = AVC1394_RESP_IMPLEMENTED;
165         default:
166                 fprintf( stderr, "unit inquiry command 0x%02x not supported\n", cr->opcode );
167                 return 0;
168         }
169         return 1;
170 }
171
172
173 /**** primary avc1394 target callback ****/
174 int command_handler( avc1394_cmd_rsp *cr )
175 {
176         switch ( cr->subunit_type )
177         {
178         case AVC1394_SUBUNIT_TYPE_FREEBOB_BOUNCE_SERVER:
179                 if ( cr->subunit_id != 0 )
180                 {
181                         fprintf( stderr, "subunit id 0x%02x not supported\n", cr->subunit_id );
182                         return 0;
183                 }
184                 switch ( cr->status )
185                 {
186                 case AVC1394_CTYP_CONTROL:
187                         return subunit_control( cr );
188                         break;
189                 case AVC1394_CTYP_STATUS:
190                         return subunit_status( cr );
191                         break;
192                 case AVC1394_CTYP_GENERAL_INQUIRY:
193                         return subunit_inquiry( cr );
194                         break;
195                 }
196                 break;
197         case AVC1394_SUBUNIT_UNIT:
198                 switch ( cr->status )
199                 {
200                 case AVC1394_CTYP_CONTROL:
201                         return unit_control( cr );
202                         break;
203                 case AVC1394_CTYP_STATUS:
204                         return unit_status( cr );
205                         break;
206                 case AVC1394_CTYP_GENERAL_INQUIRY:
207                         return unit_inquiry( cr );
208                         break;
209                 }
210                 break;
211         default:
212                 fprintf( stderr, "subunit type 0x%02x not supported\n", cr->subunit_type );
213                 return 0;
214         }
215         return 1;
216 }
217
218 struct configrom_backup {
219         quadlet_t rom[0x100];
220         size_t rom_size;
221         unsigned char rom_version;
222        
223 };
224
225 struct configrom_backup save_config_rom(raw1394handle_t handle)
226 {
227         int retval;
228         struct configrom_backup tmp;
229         /* get the current rom image */
230         retval=raw1394_get_config_rom(handle, tmp.rom, 0x100, &tmp.rom_size, &tmp.rom_version);
231 //      tmp.rom_size=rom1394_get_size(tmp.rom);
232         printf("save_config_rom get_config_rom returned %d, romsize %d, rom_version %d:\n",retval,tmp.rom_size,tmp.rom_version);
233
234         return tmp;
235 }
236
237 int restore_config_rom(raw1394handle_t handle, struct configrom_backup old)
238 {
239         int retval,i ;
240
241         quadlet_t current_rom[0x100];
242         size_t current_rom_size;
243         unsigned char current_rom_version;
244
245         retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
246         printf("restore_config_rom get_config_rom returned %d, romsize %d, rom_version %d:\n",retval,current_rom_size,current_rom_version);
247
248         printf("restore_config_rom restoring to romsize %d, rom_version %d:\n",old.rom_size,old.rom_version);
249
250         retval = raw1394_update_config_rom(handle, old.rom, old.rom_size, current_rom_version);
251         printf("restore_config_rom update_config_rom returned %d\n",retval);
252
253         /* get the current rom image */
254         retval=raw1394_get_config_rom(handle, current_rom, 0x100, &current_rom_size, &current_rom_version);
255         current_rom_size = rom1394_get_size(current_rom);
256         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,current_rom_size,current_rom_version);
257         for (i = 0; i < current_rom_size; i++)
258         {
259                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
260                 printf(" %08x", ntohl(current_rom[i]));
261         }
262         printf("\n");
263
264         return retval;
265 }
266
267 int init_config_rom(raw1394handle_t handle)
268 {
269         int retval, i;
270         quadlet_t rom[0x100];
271         size_t rom_size;
272         unsigned char rom_version;
273         rom1394_directory dir;
274         char *leaf;
275        
276         /* get the current rom image */
277         retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
278         rom_size = rom1394_get_size(rom);
279         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
280         for (i = 0; i < rom_size; i++)
281         {
282                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
283                 printf(" %08x", ntohl(rom[i]));
284         }
285         printf("\n");
286        
287         /* get the local directory */
288         rom1394_get_directory( handle, raw1394_get_local_id(handle) & 0x3f, &dir);
289        
290         /* change the vendor description for kicks */
291         i = strlen(dir.textual_leafs[0]);
292         strncpy(dir.textual_leafs[0], FREEBOB_BOUNCE_SERVER_VENDORNAME "                                          ", i);
293         retval = rom1394_set_directory(rom, &dir);
294         printf("rom1394_set_directory returned %d, romsize %d:",retval,rom_size);
295         for (i = 0; i < rom_size; i++)
296         {
297                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
298                 printf(" %08x", ntohl(rom[i]));
299         }
300         printf("\n");
301        
302         /* free the allocated mem for the textual leaves */
303         rom1394_free_directory( &dir);
304        
305         /* add an AV/C unit directory */
306         dir.unit_spec_id    = 0x0000a02d;
307         dir.unit_sw_version = 0x00010001;
308         leaf = FREEBOB_BOUNCE_SERVER_MODELNAME;
309         dir.nr_textual_leafs = 1;
310         dir.textual_leafs = &leaf;
311        
312         /* manipulate the rom */
313         retval = rom1394_add_unit( rom, &dir);
314        
315         /* get the computed size of the rom image */
316         rom_size = rom1394_get_size(rom);
317        
318         printf("rom1394_add_unit_directory returned %d, romsize %d:",retval,rom_size);
319         for (i = 0; i < rom_size; i++)
320         {
321                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
322                 printf(" %08x", ntohl(rom[i]));
323         }
324         printf("\n");
325        
326         /* convert computed rom size from quadlets to bytes before update */
327         rom_size *= sizeof(quadlet_t);
328         retval = raw1394_update_config_rom(handle, rom, rom_size, rom_version);
329         printf("update_config_rom returned %d\n",retval);
330        
331         retval=raw1394_get_config_rom(handle, rom, 0x100, &rom_size, &rom_version);
332         printf("get_config_rom returned %d, romsize %d, rom_version %d:",retval,rom_size,rom_version);
333         for (i = 0; i < rom_size; i++)
334         {
335                 if (i % 4 == 0) printf("\n0x%04x:", CSR_CONFIG_ROM+i*4);
336                 printf(" %08x", ntohl(rom[i]));
337         }
338         printf("\n");
339        
340 //      printf("You need to reload your ieee1394 modules to reset the rom.\n");
341        
342         return 0;
343 }
344
345
346 int main( int argc, char **argv )
347 {
348         raw1394handle_t handle;
349
350         signal (SIGINT, sighandler);
351         signal (SIGPIPE, sighandler);
352
353         handle = raw1394_new_handle();
354
355         if ( !handle )
356         {
357                 if ( !errno )
358                 {
359                         printf( not_compatible );
360                 }
361                 else
362                 {
363                         perror( "couldn't get handle" );
364                         printf( not_loaded );
365                 }
366                 exit( EXIT_FAILURE );
367         }
368
369         if ( raw1394_set_port( handle, 0 ) < 0 )
370         {
371                 perror( "couldn't set port" );
372                 exit( EXIT_FAILURE );
373         }
374
375         struct configrom_backup cfgrom_backup;
376         cfgrom_backup=save_config_rom( handle );
377
378         if ( init_config_rom( handle ) < 0 )
379         {
380                 perror( "couldn't init config rom!" );
381                 exit( EXIT_FAILURE );
382         }
383
384
385         avc1394_init_target( handle, command_handler );
386        
387         printf( "Starting AV/C target; press Ctrl+C to quit...\n" );
388         struct pollfd pfd = {
389                 fd: raw1394_get_fd (handle),
390                 events: POLLIN | POLLPRI,
391                 revents: 0
392         };
393         int result = 0;
394        
395
396         do {
397                 if (poll (&pfd, 1, 100) > 0 && (pfd.revents & POLLIN))
398                 result = raw1394_loop_iterate (handle);
399                
400         } while (g_done == 0 && result == 0);
401        
402         avc1394_close_target( handle );
403        
404         restore_config_rom( handle, cfgrom_backup);
405
406         printf( "Bye...\n" );
407         exit( EXIT_SUCCESS );
408 }
Note: See TracBrowser for help on using the browser.