root/branches/streaming-rework/src/libfreebobavc/ieee1394service.cpp

Revision 405, 8.5 kB (checked in by pieterpalmers, 17 years ago)

- fix some small bugs in ieee1394service and configrom
- modify bounce device's discovery routine

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* ieee1394service.cpp
2  * Copyright (C) 2005,07 by Daniel Wagner
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 "ieee1394service.h"
21
22 #include <libavc1394/avc1394.h>
23
24 #include <errno.h>
25 #include <netinet/in.h>
26
27 #include "string.h"
28
29 #include <iostream>
30 #include <iomanip>
31
32 IMPL_DEBUG_MODULE( Ieee1394Service, Ieee1394Service, DEBUG_LEVEL_NORMAL );
33
34 Ieee1394Service::Ieee1394Service()
35     : m_handle( 0 ), m_resetHandle( 0 )
36     , m_port( -1 )
37     , m_threadRunning( false )
38 {
39     pthread_mutex_init( &m_mutex, 0 );
40 }
41
42 Ieee1394Service::~Ieee1394Service()
43 {
44     stopRHThread();
45
46     if ( m_handle ) {
47         raw1394_destroy_handle( m_handle );
48     }
49     if ( m_resetHandle ) {
50         raw1394_destroy_handle( m_resetHandle );
51     }
52 }
53
54 bool
55 Ieee1394Service::initialize( int port )
56 {
57     using namespace std;
58
59     m_handle = raw1394_new_handle_on_port( port );
60     if ( !m_handle ) {
61         if ( !errno ) {
62             debugFatal("libraw1394 not compatible\n");
63         } else {
64             debugFatal("Ieee1394Service::initialize: Could not get 1394 handle: %s",
65                 strerror(errno) );
66             debugFatal("Is ieee1394 and raw1394 driver loaded?\n");
67         }
68         return false;
69     }
70
71     m_resetHandle = raw1394_new_handle_on_port( port );
72     if ( !m_handle ) {
73         if ( !errno ) {
74             debugFatal("libraw1394 not compatible\n");
75         } else {
76             debugFatal("Ieee1394Service::initialize: Could not get 1394 handle: %s",
77                 strerror(errno) );
78             debugFatal("Is ieee1394 and raw1394 driver loaded?\n");
79         }
80         return false;
81     }
82
83     m_port = port;
84
85     raw1394_set_userdata( m_handle, this );
86     raw1394_set_userdata( m_resetHandle, this );
87     raw1394_set_bus_reset_handler( m_resetHandle,
88                                    this->resetHandlerLowLevel );
89     startRHThread();
90
91     return true;
92 }
93
94 int
95 Ieee1394Service::getNodeCount()
96 {
97     return raw1394_get_nodecount( m_handle );
98 }
99
100 bool
101 Ieee1394Service::read( fb_nodeid_t nodeId,
102                        fb_nodeaddr_t addr,
103                        size_t length,
104                        fb_quadlet_t* buffer )
105 {
106     using namespace std;
107     if ( raw1394_read( m_handle, nodeId, addr, length*4, buffer ) == 0 ) {
108
109         #ifdef DEBUG
110         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,
111             "read: node 0x%X, addr = 0x%016llX, length = %u\n",
112             nodeId, addr, length);
113         printBuffer( length, buffer );
114         #endif
115
116         return true;
117     } else {
118         #ifdef DEBUG
119         debugError("raw1394_read failed: node 0x%X, addr = 0x%016llX, length = %u\n",
120               nodeId, addr, length);
121         #endif
122
123         return false;
124     }
125 }
126
127
128 bool
129 Ieee1394Service::read_quadlet( fb_nodeid_t nodeId,
130                                fb_nodeaddr_t addr,
131                                fb_quadlet_t* buffer )
132 {
133     return read( nodeId,  addr, sizeof( *buffer )/4, buffer );
134 }
135
136 bool
137 Ieee1394Service::read_octlet( fb_nodeid_t nodeId,
138                               fb_nodeaddr_t addr,
139                               fb_octlet_t* buffer )
140 {
141     return read( nodeId, addr, sizeof( *buffer )/4,
142                  reinterpret_cast<fb_quadlet_t*>( buffer ) );
143 }
144
145
146 bool
147 Ieee1394Service::write( fb_nodeid_t nodeId,
148                         fb_nodeaddr_t addr,
149                         size_t length,
150                         fb_quadlet_t* data )
151 {
152     using namespace std;
153
154     #ifdef DEBUG
155     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"write: node 0x%X, addr = 0x%016X, length = %d\n",
156                 nodeId, addr, length);
157     printBuffer( length, data );
158     #endif
159
160     return raw1394_write( m_handle, nodeId, addr, length*4, data ) == 0;
161 }
162
163
164 bool
165 Ieee1394Service::write_quadlet( fb_nodeid_t nodeId,
166                                 fb_nodeaddr_t addr,
167                                 fb_quadlet_t data )
168 {
169     return write( nodeId, addr, sizeof( data )/4, &data );
170 }
171
172 bool
173 Ieee1394Service::write_octlet( fb_nodeid_t nodeId,
174                                fb_nodeaddr_t addr,
175                                fb_octlet_t data )
176 {
177     return write( nodeId, addr, sizeof( data )/4,
178                   reinterpret_cast<fb_quadlet_t*>( &data ) );
179 }
180
181 fb_quadlet_t*
182 Ieee1394Service::transactionBlock( fb_nodeid_t nodeId,
183                                    fb_quadlet_t* buf,
184                                    int len,
185                                    unsigned int* resp_len )
186 {
187     for (int i = 0; i < len; ++i) {
188         buf[i] = ntohl( buf[i] );
189     }
190
191     #ifdef DEBUG
192     debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "  pre avc1394_transaction_block2\n" );
193     printBuffer( len, buf );
194     #endif
195
196     fb_quadlet_t* result =
197         avc1394_transaction_block2( m_handle,
198                                     nodeId,
199                                     buf,
200                                     len,
201                                     resp_len,
202                                     10 );
203
204     #ifdef DEBUG
205     debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "  post avc1394_transaction_block2\n" );
206     printBuffer( *resp_len, result );
207     #endif
208
209     for ( unsigned int i = 0; i < *resp_len; ++i ) {
210         result[i] = htonl( result[i] );
211     }
212
213     return result;
214 }
215
216
217 bool
218 Ieee1394Service::transactionBlockClose()
219 {
220     avc1394_transaction_block_close( m_handle );
221     return true;
222 }
223
224 bool
225 Ieee1394Service::setVerbose( int verboseLevel )
226 {
227     setDebugLevel(verboseLevel);
228     return true;
229 }
230
231 int
232 Ieee1394Service::getVerboseLevel()
233 {
234     return getDebugLevel();
235 }
236
237 void
238 Ieee1394Service::printBuffer( size_t length, fb_quadlet_t* buffer ) const
239 {
240
241     for ( unsigned int i=0; i < length; ++i ) {
242         if ( ( i % 4 ) == 0 ) {
243             if ( i > 0 ) {
244                 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE,"\n");
245             }
246             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE," %4d: ",i*4);
247         }
248         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE,"%08X ",buffer[i]);
249     }
250     debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE,"\n");
251 }
252
253 int
254 Ieee1394Service::resetHandlerLowLevel( raw1394handle_t handle,
255                                        unsigned int generation )
256 {
257     raw1394_update_generation ( handle, generation );
258     Ieee1394Service* instance
259         = (Ieee1394Service*) raw1394_get_userdata( handle );
260     instance->resetHandler( generation );
261
262     return 0;
263 }
264
265 bool
266 Ieee1394Service::resetHandler( unsigned int generation )
267 {
268     m_generation = generation;
269
270     for ( reset_handler_vec_t::iterator it = m_busResetHandlers.begin();
271           it != m_busResetHandlers.end();
272           ++it )
273     {
274         Functor* func = *it;
275         ( *func )();
276     }
277
278     return true;
279 }
280
281 bool
282 Ieee1394Service::startRHThread()
283 {
284     int i;
285
286     if ( m_threadRunning ) {
287         return true;
288     }
289     pthread_mutex_lock( &m_mutex );
290     i = pthread_create( &m_thread, 0, rHThread, this );
291     pthread_mutex_unlock( &m_mutex );
292     if (i) {
293         debugFatal("Could not start ieee1394 service thread\n");
294         return false;
295     }
296     m_threadRunning = true;
297
298     return true;
299 }
300
301 void
302 Ieee1394Service::stopRHThread()
303 {
304     if ( m_threadRunning ) {
305         pthread_mutex_lock (&m_mutex);
306         pthread_cancel (m_thread);
307         pthread_join (m_thread, 0);
308         pthread_mutex_unlock (&m_mutex);
309         m_threadRunning = false;
310     }
311 }
312
313 void*
314 Ieee1394Service::rHThread( void* arg )
315 {
316     Ieee1394Service* pIeee1394Service = (Ieee1394Service*) arg;
317
318     while (true) {
319         raw1394_loop_iterate (pIeee1394Service->m_resetHandle);
320         pthread_testcancel ();
321     }
322
323     return 0;
324 }
325
326 bool
327 Ieee1394Service::addBusResetHandler( Functor* functor )
328 {
329     m_busResetHandlers.push_back( functor );
330     return true;
331 }
332
333 bool
334 Ieee1394Service::remBusResetHandler( Functor* functor )
335 {
336     for ( reset_handler_vec_t::iterator it = m_busResetHandlers.begin();
337           it != m_busResetHandlers.end();
338           ++it )
339     {
340         if ( *it == functor ) {
341             m_busResetHandlers.erase( it );
342             return true;
343         }
344     }
345     return false;
346 }
Note: See TracBrowser for help on using the browser.