root/tags/release_0_0_6/libfreebob/src/libfreebobavc/avc_signal_source.cpp

Revision 156, 9.7 kB (checked in by anonymous, 18 years ago)

This commit was manufactured by cvs2svn to create tag
'release_0_0_6'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* avc_signal_source.cpp
2  * Copyright (C) 2005 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
21 #include "avc_signal_source.h"
22 #include "serialize.h"
23 #include "ieee1394service.h"
24
25 #include <netinet/in.h>
26 #include <iostream>
27
28 using namespace std;
29
30 #define AVC1394_CMD_SIGNAL_SOURCE 0x1A
31
32 SignalUnitAddress::SignalUnitAddress()
33     : m_plugId( ePI_Invalid )
34 {
35 }
36
37 bool
38 SignalUnitAddress::serialize( IOSSerialize& se )
39 {
40     byte_t reserved = 0xff;
41     se.write( reserved, "SignalUnitAddress" );
42     se.write( m_plugId, "SignalUnitAddress plugId" );
43     return true;
44 }
45
46 bool
47 SignalUnitAddress::deserialize( IISDeserialize& de )
48 {
49     byte_t operand;
50     de.read( &operand );
51     de.read( &m_plugId );
52     return true;
53 }
54
55 SignalUnitAddress*
56 SignalUnitAddress::clone() const
57 {
58     return new SignalUnitAddress( *this );
59 }
60
61 ////////////////////////////////////////
62
63 SignalSubunitAddress::SignalSubunitAddress()
64     : m_subunitType( AVC1394_SUBUNIT_RESERVED )
65     , m_subunitId( AVC1394_SUBUNIT_ID_RESERVED )
66     , m_plugId( ePI_Invalid )
67 {
68 }
69
70 bool
71 SignalSubunitAddress::serialize( IOSSerialize& se )
72 {
73     byte_t operand = ( m_subunitType << 3 ) | ( m_subunitId & 0x7 );
74     se.write( operand,  "SignalSubunitAddress subunitType & subunitId" );
75     se.write( m_plugId, "SignalSubunitAddress plugId" );
76     return true;
77 }
78
79 bool
80 SignalSubunitAddress::deserialize( IISDeserialize& de )
81 {
82     byte_t operand;
83     de.read( &operand );
84     m_subunitType = operand >> 3;
85     m_subunitId = operand & 0x7;
86     de.read( &m_plugId );
87     return true;
88 }
89
90 SignalSubunitAddress*
91 SignalSubunitAddress::clone() const
92 {
93     return new SignalSubunitAddress( *this );
94 }
95
96 ////////////////////////////////////////
97
98
99 SignalSourceCmd::SignalSourceCmd( Ieee1394Service* ieee1394service )
100     : AVCCommand( ieee1394service, AVC1394_CMD_SIGNAL_SOURCE )
101     , m_resultStatus( 0xff )
102     , m_outputStatus( 0xff )
103     , m_conv( 0xff )
104     , m_signalStatus( 0xff )
105     , m_signalSource( 0 )
106     , m_signalDestination( 0 )
107 {
108 }
109
110 SignalSourceCmd::~SignalSourceCmd()
111 {
112     delete m_signalSource;
113     m_signalSource = 0;
114     delete m_signalDestination;
115     m_signalDestination = 0;
116 }
117
118 bool
119 SignalSourceCmd::serialize( IOSSerialize& se )
120 {
121     AVCCommand::serialize( se );
122
123     byte_t operand;
124     switch ( getCommandType() ) {
125     case eCT_Status:
126         operand = ( m_outputStatus << 5 )
127                   | ( ( m_conv & 0x1 ) << 4 )
128                   | ( m_signalStatus & 0xf );
129         se.write( operand, "SignalSourceCmd outputStatus & conv & signalStatus" );
130         break;
131     case eCT_Control:
132     case eCT_SpecificInquiry:
133         operand = m_resultStatus & 0xf;
134         se.write( operand, "SignalSourceCmd resultStatus" );
135         break;
136     default:
137         cerr << "Can't handle command type " << getCommandType() << endl;
138         return false;
139     }
140
141     switch( getSubunitType() ) {
142     case eST_Unit:
143     case eST_Audio:
144     case eST_Music:
145         {
146             if ( m_signalSource ) {
147                 m_signalSource->serialize( se );
148             } else {
149                 byte_t reserved = 0xff;
150                 se.write( reserved, "SignalSourceCmd" );
151                 se.write( reserved, "SignalSourceCmd" );
152             }
153
154             if ( m_signalDestination ) {
155                 m_signalDestination->serialize( se );
156             } else {
157                 byte_t reserved = 0xff;
158                 se.write( reserved, "SignalSourceCmd" );
159                 se.write( reserved, "SignalSourceCmd" );
160             }
161         }
162         break;
163     default:
164         cerr << "Can't handle subunit type " << getSubunitType() << endl;
165         return false;
166     }
167
168     return true;
169 }
170
171 bool
172 SignalSourceCmd::deserialize( IISDeserialize& de )
173 {
174     delete m_signalSource;
175     m_signalSource = 0;
176     delete m_signalDestination;
177     m_signalDestination = 0;
178
179     AVCCommand::deserialize( de );
180
181     byte_t operand;
182     switch ( getCommandType() ) {
183     case eCT_Status:
184         de.read( &operand );
185         m_outputStatus = operand >> 5;
186         m_conv = ( operand & 0x10 ) >> 4;
187         m_signalStatus = operand & 0xf;
188         break;
189     case eCT_Control:
190     case eCT_SpecificInquiry:
191         de.read( &operand );
192         m_resultStatus = operand & 0xf;
193         break;
194     default:
195         cerr << "Can't handle command type " << getCommandType() << endl;
196         return false;
197     }
198
199     switch( getSubunitType() ) {
200     case eST_Unit:
201     case eST_Audio:
202     case eST_Music:
203         {
204             byte_t operand;
205             de.peek( &operand );
206             if ( operand == 0xff ) {
207                 m_signalSource = new SignalUnitAddress;
208             } else {
209                 m_signalSource = new SignalSubunitAddress;
210             }
211
212             m_signalSource->deserialize( de );
213
214             de.peek( &operand );
215             if ( operand == 0xff ) {
216                 m_signalDestination = new SignalUnitAddress;
217             } else {
218                 m_signalDestination = new SignalSubunitAddress;
219             }
220             m_signalDestination->deserialize( de );
221         }
222         break;
223     default:
224         cerr << "Can't handle subunit type " << getSubunitType() << endl;
225         return false;
226     }
227
228     return true;
229 }
230
231 bool
232 SignalSourceCmd::fire( raw1394handle_t handle,
233                        unsigned int node_id )
234 {
235     bool result = false;
236
237     #define STREAM_FORMAT_REQUEST_SIZE 20 // XXX random length
238     union UPacket {
239         quadlet_t     quadlet[STREAM_FORMAT_REQUEST_SIZE];
240         unsigned char byte[STREAM_FORMAT_REQUEST_SIZE*4];
241     };
242     typedef union UPacket packet_t;
243
244     packet_t  req;
245     packet_t* resp;
246
247     // initialize complete packet
248     memset( &req,  0xff,  sizeof( req ) );
249
250     BufferSerialize se( req.byte, sizeof( req ) );
251     if ( !serialize( se ) ) {
252         printf(  "SignalSourceCmd::fire: Could not serialize\n" );
253         return false;
254     }
255
256     // reorder the bytes to the correct layout
257     for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
258         req.quadlet[i] = ntohl( req.quadlet[i] );
259     }
260
261     if ( isVerbose() ) {
262         // debug output
263         puts("request:");
264         for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
265             printf("  %2d: 0x%08x\n", i, req.quadlet[i]);
266         }
267     }
268
269     resp = reinterpret_cast<packet_t*>(
270         m_1394Service->transactionBlock( m_nodeId,
271                                          req.quadlet,
272                                          STREAM_FORMAT_REQUEST_SIZE ) );
273     if ( resp ) {
274         if ( isVerbose() ) {
275             // debug output
276             puts("response:");
277             for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
278                 printf( "  %2d: 0x%08x\n", i, resp->quadlet[i] );
279             }
280         }
281
282         // reorder the bytes to the correct layout
283         for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
284             resp->quadlet[i] = htonl( resp->quadlet[i] );
285         }
286
287         if ( isVerbose() ) {
288             // a more detailed debug output
289             printf( "\n" );
290             printf( " idx type                       value\n" );
291             printf( "-------------------------------------\n" );
292             printf( "  %02d                     ctype: 0x%02x\n", 0, resp->byte[0] );
293             printf( "  %02d subunit_type + subunit_id: 0x%02x\n", 1, resp->byte[1] );
294             printf( "  %02d                    opcode: 0x%02x\n", 2, resp->byte[2] );
295
296             for ( int i = 3; i < STREAM_FORMAT_REQUEST_SIZE * 4; ++i ) {
297                 printf( "  %02d                operand %2d: 0x%02x\n", i, i-3, resp->byte[i] );
298             }
299         }
300
301         // parse output
302         parseResponse( resp->byte[0] );
303         switch ( getResponse() )
304         {
305         case eR_Implemented:
306         case eR_NotImplemented:
307         case eR_Accepted:
308         case eR_Rejected:
309             {
310                 BufferDeserialize de( resp->byte, sizeof( req ) );
311                 deserialize( de );
312                 result = true;
313             }
314             break;
315         default:
316             printf( "unexpected response received (0x%x)\n", getResponse() );
317         }
318     } else {
319         printf( "no response\n" );
320     }
321
322     return result;
323 }
324
325 bool
326 SignalSourceCmd::setSignalSource( SignalUnitAddress& signalAddress )
327 {
328     if ( m_signalSource ) {
329         delete m_signalSource;
330     }
331     m_signalSource = signalAddress.clone();
332     return true;
333 }
334
335 bool
336 SignalSourceCmd::setSignalSource( SignalSubunitAddress& signalAddress )
337 {
338     if ( m_signalSource ) {
339         delete m_signalSource;
340     }
341     m_signalSource = signalAddress.clone();
342     return true;
343 }
344
345 bool
346 SignalSourceCmd::setSignalDestination( SignalUnitAddress& signalAddress )
347 {
348     if ( m_signalDestination ) {
349         delete m_signalDestination;
350     }
351     m_signalDestination = signalAddress.clone();
352     return true;
353 }
354
355 bool
356 SignalSourceCmd::setSignalDestination( SignalSubunitAddress& signalAddress )
357 {
358     if ( m_signalDestination ) {
359         delete m_signalDestination;
360     }
361     m_signalDestination = signalAddress.clone();
362     return true;
363 }
364
365 SignalAddress*
366 SignalSourceCmd::getSignalSource()
367 {
368     return m_signalSource;
369 }
370
371 SignalAddress*
372 SignalSourceCmd::getSignalDestination()
373 {
374     return m_signalDestination;
375 }
Note: See TracBrowser for help on using the browser.