root/trunk/freebob/src/avdevice.cpp

Revision 35, 9.7 kB (checked in by pieterpalmers, 19 years ago)

- code merge
- some more experiments

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* avdevice.cpp
2  * Copyright (C) 2004 by Daniel Wagner, Pieter Palmers
3  *
4  * This file is part of FreeBob.
5  *
6  * FreeBob is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBob is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBob; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20 #include <errno.h>
21 #include <libavc1394/avc1394.h>
22 #include <libavc1394/avc1394_vcr.h>
23 #include "debugmodule.h"
24 #include "avdevice.h"
25 #include "avdevicesubunit.h"
26 #include "avdeviceaudiosubunit.h"
27 #include "avdevicemusicsubunit.h"
28
29 AvDevice::AvDevice(int port, int node)
30 {
31         iNodeId=node;
32         m_iPort=port;
33
34         // check to see if a device is really present?
35
36         // probably initialisation would be better done here
37
38         // Port and node id are not distinct.  The node id
39         // can change after a bus reset, therefore the
40         // device id has to be taken for identifiction.
41 }
42
43 FBReturnCodes
44 AvDevice::Initialize() {
45    if (!m_bInitialised) {
46
47         m_handle = raw1394_new_handle();
48         if ( !m_handle ) {
49             if ( !errno ) {
50                 debugPrint(DEBUG_LEVEL_DEVICE,  "libraw1394 not compatible.\n" );
51             } else {
52                 perror ("Could not get 1394 handle");
53                 debugPrint(DEBUG_LEVEL_DEVICE, "Is ieee1394 and raw1394 driver loaded?\n");
54             }
55             return eFBRC_Creating1394HandleFailed;
56         }
57
58         raw1394_set_userdata( m_handle, this );
59
60         if ( raw1394_set_port( m_handle,  m_iPort ) < 0 ) {
61             perror( "Could not set port" );
62             return eFBRC_Setting1394PortFailed;
63         }
64    }
65
66    // enumerate the subunits present in this device, create an AvDeviceSubunit for them, and add this object to the cSubUnits vector
67         unsigned char table_entry;
68         unsigned char subunit_maxid;
69         unsigned char subunit_type;
70         quadlet_t table_entries; // buffer these table entries, because the memory content pointed to by
71                                  // the response pointer can change due to other libraw operations on this handle
72
73         quadlet_t request[6];
74         quadlet_t *response;
75         AvDeviceSubunit *tmpAvDeviceSubunit=NULL;
76
77         // check the number of I/O plugs
78
79         request[0] = AVC1394_CTYPE_STATUS | AVC1394_SUBUNIT_TYPE_UNIT | AVC1394_SUBUNIT_ID_IGNORE
80                                         | AVC1394_COMMAND_PLUG_INFO | 0x00;
81         request[1] = 0xFFFFFFFF;
82         response = avcExecuteTransaction(request, 2, 2);
83         if (response != NULL) {
84                 iNbIsoDestinationPlugs= (unsigned char) ((response[1]>>24) & 0xff);
85                 iNbIsoSourcePlugs= (unsigned char) ((response[1]>>16) & 0xff);
86                 iNbExtDestinationPlugs= (unsigned char) ((response[1]>>8) & 0xff);
87                 iNbExtSourcePlugs= (unsigned char) ((response[1]>>0) & 0xff);
88         }
89         request[0] = AVC1394_CTYPE_STATUS | AVC1394_SUBUNIT_TYPE_UNIT | AVC1394_SUBUNIT_ID_IGNORE
90                                         | AVC1394_COMMAND_PLUG_INFO | 0x01;
91         request[1] = 0xFFFFFFFF;
92         response = avcExecuteTransaction(request, 2, 2);
93         if (response != NULL) {
94                 iNbAsyncDestinationPlugs= (unsigned char) ((response[1]>>24) & 0xff);
95                 iNbAsyncSourcePlugs= (unsigned char) ((response[1]>>16) & 0xff);
96         }
97
98         debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: %d Isochronous source plugs, %d Isochronous destination plugs\n",iNbIsoSourcePlugs,iNbIsoDestinationPlugs);
99         debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: %d External source plugs, %d External destination plugs\n",iNbExtSourcePlugs,iNbExtDestinationPlugs);
100         debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: %d Asynchronous source plugs, %d Asynchronous destination plugs\n",iNbAsyncSourcePlugs,iNbAsyncDestinationPlugs);
101
102         // create the subunits
103         for (unsigned int i=0;i<8;i++) { // cycle through the 8 pages (max 32 subunits; 4 subunits/page)
104                 request[0] = AVC1394_CTYPE_STATUS | AVC1394_SUBUNIT_TYPE_UNIT | AVC1394_SUBUNIT_ID_IGNORE
105                                 | AVC1394_COMMAND_SUBUNIT_INFO | ((i<<4) & 0xF0) | 0x07;
106                 request[1] = 0xFFFFFFFF;
107                 response = avcExecuteTransaction(request, 6, 2);
108
109                 table_entries=response[1];
110
111                 if (response != NULL) {
112                         // this way of processing the table entries assumes that the subunit type is not "extended"
113
114                         // stop processing when a "not implemented" is received (according to spec)
115                         if((response[0]&0xFF000000) == AVC1394_RESPONSE_NOT_IMPLEMENTED) break;
116
117                         // warning: don't do unsigned int j! comparison >= 0 is always true for uint
118                         for (int j=3;j>=0;j--) { // cycle through the 8 pages (max 32 subunits; 4 subunits/page)
119                                 table_entry=(table_entries >> (j*8)) & 0xFF;
120                                 subunit_maxid=table_entry& 0x07;
121                                 subunit_type=(table_entry >> 3) & 0x1F;
122                                 //debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: Page %d, item %d: Table entry=0x%02X, subunit_maxid=0x%02X, subunit_type=0x%02X\n",i,j,table_entry,subunit_maxid,subunit_type);
123
124                                 // according to spec we could stop processing
125                                 // at the first 0xFF entry, but doing it this way
126                                 // is a little more robust
127                                 if (table_entry != 0xFF) {
128                                         for (unsigned char subunit_id=0;subunit_id<subunit_maxid+1;subunit_id++) {
129
130                                                 // only two types of specific subunits are supported: audio and music
131                                                 switch (subunit_type) {
132                                                         case 0x01: // audio subunit
133                                                                 tmpAvDeviceSubunit=new AvDeviceAudioSubunit(this,subunit_id);
134                                                                 if (tmpAvDeviceSubunit) { // test code
135                                                                         //tmpAvDeviceSubunit->printOutputPlugConnections();
136                                                                 }
137                                                         break;
138                                                         case 0x0C: // music subunit
139                                                                 tmpAvDeviceSubunit=new AvDeviceMusicSubunit(this,subunit_id);
140                                                                 { // just a test
141                                                                 AvDeviceMusicSubunit tmpAvDeviceSubunit2(this,subunit_id);
142                                                                 tmpAvDeviceSubunit2.printMusicPlugInfo();
143                                                                 tmpAvDeviceSubunit2.printMusicPlugConfigurations();
144                                                                 tmpAvDeviceSubunit2.printOutputPlugConnections();
145                                                                 tmpAvDeviceSubunit2.test();
146                                                                 }
147                                                         break;
148
149                                                         default: // generic
150                                                                 tmpAvDeviceSubunit=new AvDeviceSubunit(this,subunit_type,subunit_id);
151                                                         break;
152                                                 }
153
154                                                 if(tmpAvDeviceSubunit && tmpAvDeviceSubunit->isValid()) {
155                                                         cSubUnits.push_back(tmpAvDeviceSubunit);
156
157
158                                                 } else {
159                                                         if (tmpAvDeviceSubunit) {
160                                                                 debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: Unsupported AvDeviceSubunit encountered. Page %d, item %d: Table entry=0x%02X, subunit_maxid=0x%02X, subunit_type=0x%02X, subunit_id=%0x02X\n",i,j,table_entry,subunit_maxid,subunit_type,subunit_id);
161
162                                                                 delete tmpAvDeviceSubunit;
163                                                         } else {
164                                                                 debugPrint (DEBUG_LEVEL_DEVICE,"AvDevice: Could not create AvDeviceSubunit object.\n");
165                                                         }
166                                                 }
167                                         }
168                                 }
169                         }
170                 }
171         }
172
173    m_bInitialised = true;
174    return eFBRC_Success;
175
176 }
177
178 bool AvDevice::isInitialised() {
179         return m_bInitialised;
180 }
181
182 AvDevice::~AvDevice()
183 {
184
185         vector<AvDeviceSubunit *>::iterator it;
186         for( it = cSubUnits.begin(); it != cSubUnits.end(); it++ ) {
187                 delete *it;
188         }
189
190     if ( m_handle ) {
191         raw1394_destroy_handle( m_handle );
192         m_handle = 0;
193     }
194 }
195
196 /* Function to execute an AVC transaction, i.e. send command/status and get response
197  * main purpose is wrapping the avc1394 function call to output some debugging comments.
198  */
199 quadlet_t * AvDevice::avcExecuteTransaction(quadlet_t *request, unsigned int request_len, unsigned int response_len) {
200         quadlet_t *response;
201         unsigned char *request_pos;
202         unsigned int i;
203         response = avc1394_transaction_block(m_handle, iNodeId, request, request_len, 2);
204         if (request != NULL) {
205                 debugPrint (DEBUG_LEVEL_TRANSFERS, "\n------- TRANSACTION START -------\n");
206                 debugPrint (DEBUG_LEVEL_TRANSFERS,"  REQUEST:     ");
207                 /* request is in machine byte order. this function is for intel architecure */
208                 for (i=0;i<request_len;i++) {
209                         request_pos=(unsigned char *)(request+i);
210                         debugPrint (DEBUG_LEVEL_TRANSFERS, "0x%02X%02X%02X%02X ", *(request_pos),*(request_pos+1),*(request_pos+2),*(request_pos+3));
211                 }
212                 debugPrint (DEBUG_LEVEL_TRANSFERS,"\n");
213                 debugPrint (DEBUG_LEVEL_TRANSFERS,"      => ");
214                 debugPrint (DEBUG_LEVEL_TRANSFERS,"                     ");
215                 request_pos=(unsigned char *)(request);
216                 debugPrint (DEBUG_LEVEL_TRANSFERS, "subunit_type=%02X  subunit_id=%02X  opcode=%02X",((*(request_pos+1))>>3)&0x1F,(*(request_pos+1))&0x07,(*(request_pos+2))&0xFF);
217                 debugPrint (DEBUG_LEVEL_TRANSFERS,"\n");
218         }
219         if (response != NULL) {
220                 /* response is in order of receiving, i.e. msb first */
221                 debugPrint (DEBUG_LEVEL_TRANSFERS,"  -> RESPONSE: ");
222                 for (i=0;i<response_len;i++) {
223                         debugPrint (DEBUG_LEVEL_TRANSFERS, "0x%08X ", response[i]);
224                 }
225                 debugPrint (DEBUG_LEVEL_TRANSFERS,"\n");
226                 debugPrint (DEBUG_LEVEL_TRANSFERS,"      => ");
227                 switch (response[0]&0xFF000000) {
228                         case AVC1394_RESPONSE_NOT_IMPLEMENTED:
229                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Not Implemented      ");
230                         break;
231                         case AVC1394_RESPONSE_ACCEPTED:
232                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Accepted             ");
233                         break;
234                         case AVC1394_RESPONSE_REJECTED:
235                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Rejected             ");
236                         break;
237                         case AVC1394_RESPONSE_IN_TRANSITION:
238                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"In Transition        ");
239                         break;
240                         case AVC1394_RESPONSE_IMPLEMENTED:
241                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Implemented / Stable ");
242                         break;
243                         case AVC1394_RESPONSE_CHANGED:
244                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Changed              ");
245                         break;
246                         case AVC1394_RESPONSE_INTERIM:
247                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Interim              ");
248                         break;
249                         default:
250                                 debugPrint (DEBUG_LEVEL_TRANSFERS,"Unknown response     ");
251                         break;
252                 }
253                 debugPrint (DEBUG_LEVEL_TRANSFERS, "subunit_type=%02X  subunit_id=%02X  opcode=%02X",(response[0]>>19)&0x1F,(response[0]>>16)&0x07,(response[0]>>8)&0xFF);
254                 debugPrint (DEBUG_LEVEL_TRANSFERS,"\n");
255         }
256         debugPrint (DEBUG_LEVEL_TRANSFERS, "------- TRANSACTION END -------\n");
257         return response;
258
259 }
Note: See TracBrowser for help on using the browser.