Clean up compiler warnings when compiling on 64-bit systems. These are mostly fixing...
[ffado.git] / libffado / src / fireworks / fireworks_control.cpp
blob25c64581c4c6baeff70fd16c8c3fbfd0242ba0bf
1 /*
2 * Copyright (C) 2005-2008 by Pieter Palmers
4 * This file is part of FFADO
5 * FFADO = Free Firewire (pro-)audio drivers for linux
7 * FFADO is based upon FreeBoB.
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) version 3 of the License.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "fireworks_device.h"
25 #include "fireworks_control.h"
26 #include "efc/efc_avc_cmd.h"
27 #include "efc/efc_cmd.h"
28 #include "efc/efc_cmds_mixer.h"
29 #include "efc/efc_cmds_monitor.h"
30 #include "efc/efc_cmds_hardware_ctrl.h"
32 #include <string>
33 #include <sstream>
35 using namespace std;
37 // These classes provide support for the controls on the echo devices
38 namespace FireWorks {
40 MonitorControl::MonitorControl(FireWorks::Device& p, enum eMonitorControl c)
41 : Control::MatrixMixer(&p, "MonitorControl")
42 , m_control(c)
43 , m_ParentDevice(p)
47 MonitorControl::MonitorControl(FireWorks::Device& p, enum eMonitorControl c, std::string n)
48 : Control::MatrixMixer(&p, n)
49 , m_control(c)
50 , m_ParentDevice(p)
54 void MonitorControl::show()
56 debugOutput(DEBUG_LEVEL_NORMAL, "MonitorControl\n");
59 std::string MonitorControl::getRowName( const int row )
61 std::ostringstream rowname;
62 rowname << "IN" << row;
63 debugOutput(DEBUG_LEVEL_VERBOSE, "name for row %d is %s\n",
64 row, rowname.str().c_str());
65 return rowname.str();
68 std::string MonitorControl::getColName( const int col )
70 std::ostringstream colname;
71 colname << "OUT" << col;
72 debugOutput(DEBUG_LEVEL_VERBOSE, "name for col %d is %s\n",
73 col, colname.str().c_str());
74 return colname.str();
77 int MonitorControl::canWrite( const int row, const int col )
79 debugOutput(DEBUG_LEVEL_VERBOSE, "canWrite for row %d col %d is %d\n",
80 row, col, true);
81 return true;
84 double MonitorControl::setValue( const int row, const int col, const double val )
86 double retval=0.0;
87 bool did_command=false;
89 if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) {
90 debugError("specified row (%u) larger than number of rows (%d)\n",
91 row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in);
92 return 0.0;
94 if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) {
95 debugError("specified col (%u) larger than number of cols (%d)\n",
96 col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out);
97 return 0.0;
100 // not a switch since we create variables
101 if(m_control==eMC_Gain) {
102 EfcSetMonitorGainCmd setCmd;
103 setCmd.m_input = row;
104 setCmd.m_output = col;
105 setCmd.m_value = (uint32_t)val;
106 if (!m_ParentDevice.doEfcOverAVC(setCmd))
108 debugError("Cmd failed\n");
110 // update the session block
111 m_ParentDevice.m_session.h.monitorgains[row][col] = setCmd.m_value;
112 retval = setCmd.m_value;
113 did_command = true;
115 if(m_control==eMC_Pan) {
116 EfcSetMonitorPanCmd setCmd;
117 setCmd.m_input = row;
118 setCmd.m_output = col;
119 setCmd.m_value = (uint32_t)val;
120 if (!m_ParentDevice.doEfcOverAVC(setCmd))
122 debugError("Cmd failed\n");
124 // update the session block
125 m_ParentDevice.m_session.s.monitorpans[row][col] = setCmd.m_value;
126 retval = setCmd.m_value;
127 did_command = true;
129 if(m_control==eMC_Mute) {
130 EfcSetMonitorMuteCmd setCmd;
131 setCmd.m_input = row;
132 setCmd.m_output = col;
133 setCmd.m_value = (uint32_t)val;
134 if (!m_ParentDevice.doEfcOverAVC(setCmd))
136 debugError("Cmd failed\n");
138 // update the session block
139 if(setCmd.m_value) {
140 m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_MUTE_BIT;
141 } else {
142 m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_MUTE_BIT;
144 retval = setCmd.m_value;
145 did_command = true;
147 if(m_control==eMC_Solo) {
148 EfcSetMonitorSoloCmd setCmd;
149 setCmd.m_input = row;
150 setCmd.m_output = col;
151 setCmd.m_value = (uint32_t)val;
152 if (!m_ParentDevice.doEfcOverAVC(setCmd))
154 debugError("Cmd failed\n");
156 // update the session block
157 if(setCmd.m_value) {
158 m_ParentDevice.m_session.s.monitorflags[row][col] |= ECHO_SESSION_SOLO_BIT;
159 } else {
160 m_ParentDevice.m_session.s.monitorflags[row][col] &= ~ECHO_SESSION_SOLO_BIT;
162 retval = setCmd.m_value;
163 did_command = true;
166 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for row %d col %d = %lf\n",
167 row, col, retval);
169 if (!did_command) {
170 debugError("BUG: this should never happen due to enum\n");
172 return retval;
175 double MonitorControl::getValue( const int row, const int col )
177 double retval=0.0;
178 bool did_command=false;
180 if(row >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_in) {
181 debugError("specified row (%u) larger than number of rows (%d)\n",
182 row, m_ParentDevice.getHwInfo().m_nb_phys_audio_in);
183 return 0.0;
185 if(col >= (int)m_ParentDevice.getHwInfo().m_nb_phys_audio_out) {
186 debugError("specified col (%u) larger than number of cols (%d)\n",
187 col, m_ParentDevice.getHwInfo().m_nb_phys_audio_out);
188 return 0.0;
191 if(m_control==eMC_Gain) {
192 EfcGetMonitorGainCmd getCmd;
193 getCmd.m_input=row;
194 getCmd.m_output=col;
195 if (!m_ParentDevice.doEfcOverAVC(getCmd))
197 debugError("Cmd failed\n");
199 retval=getCmd.m_value;
200 did_command=true;
202 if(m_control==eMC_Pan) {
203 EfcGetMonitorPanCmd getCmd;
204 getCmd.m_input=row;
205 getCmd.m_output=col;
206 if (!m_ParentDevice.doEfcOverAVC(getCmd))
208 debugError("Cmd failed\n");
210 retval=getCmd.m_value;
211 did_command=true;
213 if(m_control==eMC_Mute) {
214 EfcGetMonitorMuteCmd getCmd;
215 getCmd.m_input=row;
216 getCmd.m_output=col;
217 if (!m_ParentDevice.doEfcOverAVC(getCmd))
219 debugError("Cmd failed\n");
221 retval=getCmd.m_value;
222 did_command=true;
224 if(m_control==eMC_Solo) {
225 EfcGetMonitorSoloCmd getCmd;
226 getCmd.m_input=row;
227 getCmd.m_output=col;
228 if (!m_ParentDevice.doEfcOverAVC(getCmd))
230 debugError("Cmd failed\n");
232 retval=getCmd.m_value;
233 did_command=true;
236 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for row %d col %d = %lf\n",
237 row, col, retval);
239 if (!did_command) {
240 debugError("BUG: this should never happen due to enum\n");
242 return retval;
245 int MonitorControl::getRowCount( )
247 return m_ParentDevice.getHwInfo().m_nb_phys_audio_in;
250 int MonitorControl::getColCount( )
252 return m_ParentDevice.getHwInfo().m_nb_phys_audio_out;
255 // --- the generic control element for single-value controls
257 SimpleControl::SimpleControl(FireWorks::Device& p,
258 enum eMixerTarget t,
259 enum eMixerCommand c,
260 int channel)
261 : Control::Continuous(&p, "SimpleControl")
262 , m_Slave(new EfcGenericMixerCmd(t, c, channel))
263 , m_ParentDevice(p)
267 SimpleControl::SimpleControl(FireWorks::Device& p,
268 enum eMixerTarget t,
269 enum eMixerCommand c,
270 int channel,
271 std::string n)
272 : Control::Continuous(&p, n)
273 , m_Slave(new EfcGenericMixerCmd(t, c, channel))
274 , m_ParentDevice(p)
278 SimpleControl::~SimpleControl()
280 delete m_Slave;
283 void SimpleControl::show()
285 debugOutput(DEBUG_LEVEL_NORMAL, "SimpleControl\n");
286 if(m_Slave) m_Slave->showEfcCmd();
289 bool SimpleControl::setValue( const double val )
291 if(m_Slave) {
292 m_Slave->setType(eCT_Set);
293 m_Slave->m_value = (uint32_t)val;
294 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
296 debugError("Cmd failed\n");
297 return 0.0;
300 // update the session block
301 switch(m_Slave->getTarget()) {
302 case eMT_PlaybackMix:
303 switch(m_Slave->getCommand()) {
304 case eMC_Gain:
305 m_ParentDevice.m_session.h.playbackgains[m_Slave->m_channel] = m_Slave->m_value;
306 break;
307 default: // nothing
308 break;
310 break;
311 case eMT_PhysicalOutputMix:
312 switch(m_Slave->getCommand()) {
313 case eMC_Gain:
314 m_ParentDevice.m_session.h.outputgains[m_Slave->m_channel] = m_Slave->m_value;
315 break;
316 default: // nothing
317 break;
319 break;
320 default: // nothing
321 break;
323 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %lf = %u\n",
324 m_Slave->m_channel, val, m_Slave->m_value);
325 return true;
326 } else {
327 debugError("No slave EFC command present\n");
328 return false;
332 double SimpleControl::getValue( )
334 if(m_Slave) {
335 m_Slave->setType(eCT_Get);
336 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
338 debugError("Cmd failed\n");
339 return 0.0;
341 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for channel %d = %u\n",
342 m_Slave->m_channel, m_Slave->m_value);
343 return m_Slave->m_value;
344 } else {
345 debugError("No slave EFC command present\n");
346 return 0.0;
350 // --- the generic control element for on-off controls
352 BinaryControl::BinaryControl(FireWorks::Device& p,
353 enum eMixerTarget t,
354 enum eMixerCommand c,
355 int channel, int bit)
356 : Control::Discrete(&p, "BinaryControl")
357 , m_bit(bit)
358 , m_Slave(new EfcGenericMixerCmd(t, c, channel))
359 , m_ParentDevice(p)
363 BinaryControl::BinaryControl(FireWorks::Device& p,
364 enum eMixerTarget t,
365 enum eMixerCommand c,
366 int channel, int bit,
367 std::string n)
368 : Control::Discrete(&p, n)
369 , m_bit(bit)
370 , m_Slave(new EfcGenericMixerCmd(t, c, channel))
371 , m_ParentDevice(p)
375 BinaryControl::~BinaryControl()
377 delete m_Slave;
380 void BinaryControl::show()
382 debugOutput(DEBUG_LEVEL_NORMAL, "BinaryControl\n");
383 if(m_Slave) m_Slave->showEfcCmd();
386 bool BinaryControl::setValue( const int val )
389 if(m_Slave) {
390 uint32_t reg;
391 uint32_t old_reg;
393 m_Slave->setType(eCT_Get);
394 reg=m_Slave->m_value;
396 old_reg=reg;
397 if (val) {
398 reg |= (1<<m_bit);
399 } else {
400 reg &= ~(1<<m_bit);
403 m_Slave->setType(eCT_Set);
404 m_Slave->m_value=reg;
405 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
407 debugError("Cmd failed\n");
408 return 0;
411 // update the session block
412 switch(m_Slave->getTarget()) {
413 case eMT_PlaybackMix:
414 switch(m_Slave->getCommand()) {
415 case eMC_Mute:
416 m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].mute = m_Slave->m_value;
417 break;
418 case eMC_Solo:
419 m_ParentDevice.m_session.s.playbacks[m_Slave->m_channel].solo = m_Slave->m_value;
420 break;
421 default: // nothing
422 break;
424 break;
425 case eMT_PhysicalOutputMix:
426 switch(m_Slave->getCommand()) {
427 case eMC_Mute:
428 m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].mute = m_Slave->m_value;
429 break;
430 case eMC_Nominal:
431 m_ParentDevice.m_session.s.outputs[m_Slave->m_channel].shift = m_Slave->m_value;
432 break;
433 default: // nothing
434 break;
436 break;
437 case eMT_PhysicalInputMix:
438 switch(m_Slave->getCommand()) {
439 //case eMC_Pad:
440 // m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].pad = m_Slave->m_value;
441 // break;
442 case eMC_Nominal:
443 m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift = m_Slave->m_value;
444 break;
445 default: // nothing
446 break;
448 break;
449 default: // nothing
450 break;
453 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for channel %d to %d (reg: 0x%08X => 0x%08X)\n",
454 m_Slave->m_channel, val, old_reg, reg);
455 return true;
456 } else {
457 debugError("No slave EFC command present\n");
458 return false;
462 int BinaryControl::getValue( )
464 if(m_Slave) {
465 // workaround for the failing get nominal command for input channels
466 // get it from the session block
467 if ((m_Slave->getTarget() == eMT_PhysicalInputMix)
468 && (m_Slave->getCommand() == eMC_Nominal)) {
469 int val = m_ParentDevice.m_session.s.inputs[m_Slave->m_channel].shift;
470 debugOutput(DEBUG_LEVEL_VERBOSE, "input pad workaround: %08X\n", val);
471 return val;
473 m_Slave->setType(eCT_Get);
474 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
476 debugError("Cmd failed\n");
477 return 0;
479 bool val= (m_Slave->m_value & (1<<m_bit)) != 0;
480 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for channel %d: reg: 0x%08X, result=%d\n",
481 m_Slave->m_channel, m_Slave->m_value, val);
482 return val;
483 } else {
484 debugError("No slave EFC command present\n");
485 return 0;
489 // --- control element for flags
491 SpdifModeControl::SpdifModeControl(FireWorks::Device& parent)
492 : Control::Discrete(&parent, "SpdifModeControl")
493 , m_ParentDevice(parent)
497 SpdifModeControl::SpdifModeControl(FireWorks::Device& parent,
498 std::string n)
499 : Control::Discrete(&parent, n)
500 , m_ParentDevice(parent)
504 SpdifModeControl::~SpdifModeControl()
508 void SpdifModeControl::show()
510 debugOutput(DEBUG_LEVEL_NORMAL, "SpdifModeControl\n");
513 bool SpdifModeControl::setValue( const int val )
515 EfcChangeFlagsCmd setCmd;
516 if(val) {
517 setCmd.m_setmask = FIREWORKS_EFC_FLAG_SPDIF_PRO;
518 } else {
519 setCmd.m_clearmask = FIREWORKS_EFC_FLAG_SPDIF_PRO;
521 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue val: %d setmask: %08X, clear: %08X\n",
522 val, setCmd.m_setmask, setCmd.m_clearmask);
523 if (!m_ParentDevice.doEfcOverAVC(setCmd))
525 debugError("Cmd failed\n");
526 return false;
528 return true;
531 int SpdifModeControl::getValue( )
533 EfcGetFlagsCmd getCmd;
534 if (!m_ParentDevice.doEfcOverAVC(getCmd))
536 debugError("Cmd failed\n");
537 return 0;
539 debugOutput(DEBUG_LEVEL_VERBOSE, "got flags: %08X\n",
540 getCmd.m_flags);
541 if(getCmd.m_flags & FIREWORKS_EFC_FLAG_SPDIF_PRO) return 1;
542 else return 0;
545 // --- io config controls
547 IOConfigControl::IOConfigControl(FireWorks::Device& parent,
548 enum eIOConfigRegister r)
549 : Control::Discrete(&parent, "IOConfigControl")
550 , m_Slave(new EfcGenericIOConfigCmd(r))
551 , m_ParentDevice(parent)
555 IOConfigControl::IOConfigControl(FireWorks::Device& parent,
556 enum eIOConfigRegister r,
557 std::string n)
558 : Control::Discrete(&parent, n)
559 , m_Slave(new EfcGenericIOConfigCmd(r))
560 , m_ParentDevice(parent)
564 IOConfigControl::~IOConfigControl()
566 delete m_Slave;
569 void IOConfigControl::show()
571 debugOutput(DEBUG_LEVEL_NORMAL, "IOConfigControl\n");
572 if(m_Slave) m_Slave->showEfcCmd();
575 bool IOConfigControl::setValue( const int val )
577 if(m_Slave) {
578 m_Slave->setType(eCT_Set);
579 m_Slave->m_value=val;
580 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
582 debugError("Cmd failed\n");
583 return 0;
585 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue to %d \n", val);
586 return true;
587 } else {
588 debugError("No slave EFC command present\n");
589 return false;
593 int IOConfigControl::getValue( )
595 if(m_Slave) {
596 m_Slave->setType(eCT_Get);
597 if (!m_ParentDevice.doEfcOverAVC(*m_Slave))
599 debugError("Cmd failed\n");
600 return 0;
602 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue: result=%d\n",
603 m_Slave->m_value);
604 return m_Slave->m_value;
605 } else {
606 debugError("No slave EFC command present\n");
607 return 0;
611 // PlaybackRouting controls
613 PlaybackRoutingControl::PlaybackRoutingControl(FireWorks::Device& parent)
614 : Control::Discrete(&parent, "PlaybackRouting")
615 , m_ParentDevice(parent)
619 PlaybackRoutingControl::PlaybackRoutingControl(FireWorks::Device& parent, std::string n)
620 : Control::Discrete(&parent, n)
621 , m_ParentDevice(parent)
625 PlaybackRoutingControl::~PlaybackRoutingControl()
629 void PlaybackRoutingControl::show()
631 debugOutput(DEBUG_LEVEL_NORMAL, "PlaybackRouting\n");
634 bool PlaybackRoutingControl::GetState(EfcIsocMapIOConfigCmd *cmd)
636 cmd->m_num_playmap_entries = 3;
637 cmd->m_playmap[0] = 0;
638 cmd->m_playmap[1] = 0;
639 cmd->m_playmap[2] = 0;
641 cmd->setType(eCT_Get);
642 if (!m_ParentDevice.doEfcOverAVC(*cmd))
643 return false;
645 return true;
649 bool PlaybackRoutingControl::setValue(int idx, int v)
651 EfcIsocMapIOConfigCmd setCmd;
654 * NOTE:
655 * Playback Stream ch1/2: 0
656 * Playback Stream ch3/4: 2
657 * Playback Stream ch5/6: 4
659 unsigned int value = v * 2;
661 if (!GetState(&setCmd)) {
662 debugError("Cmd failed\n");
663 return false;
666 setCmd.m_playmap[idx] = value;
668 setCmd.setType(eCT_Set);
669 if (!m_ParentDevice.doEfcOverAVC(setCmd)) {
670 debugError("Cmd failed\n");
671 return false;
674 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue: result=%d:%d\n",
675 idx,
676 setCmd.m_playmap[idx]);
678 return true;
681 int PlaybackRoutingControl::getValue(int idx)
683 EfcIsocMapIOConfigCmd getCmd;
684 GetState(&getCmd);
686 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue: result=[%d][%d][%d]\n",
687 getCmd.m_playmap[0],
688 getCmd.m_playmap[1],
689 getCmd.m_playmap[2]);
691 return getCmd.m_playmap[idx] / 2;
694 // control to get hardware information
695 HwInfoControl::HwInfoControl(FireWorks::Device& p,
696 enum eHwInfoField f)
697 : Control::Discrete(&p, "HwInfoControl")
698 , m_ParentDevice(p)
699 , m_Field(f)
703 HwInfoControl::HwInfoControl(FireWorks::Device& p,
704 enum eHwInfoField f,
705 std::string n)
706 : Control::Discrete(&p, n)
707 , m_ParentDevice(p)
708 , m_Field(f)
712 HwInfoControl::~HwInfoControl()
716 int HwInfoControl::getValue()
718 switch (m_Field) {
719 case eHIF_PhysicalAudioOutCount:
720 return m_ParentDevice.getHwInfo().m_nb_phys_audio_out;
721 case eHIF_PhysicalAudioInCount:
722 return m_ParentDevice.getHwInfo().m_nb_phys_audio_in;
723 case eHIF_1394PlaybackCount:
724 return m_ParentDevice.getHwInfo().m_nb_1394_playback_channels;
725 case eHIF_1394RecordCount:
726 return m_ParentDevice.getHwInfo().m_nb_1394_record_channels;
727 case eHIF_GroupOutCount:
728 return m_ParentDevice.getHwInfo().m_nb_out_groups;
729 case eHIF_GroupInCount:
730 return m_ParentDevice.getHwInfo().m_nb_in_groups;
731 case eHIF_PhantomPower:
732 return m_ParentDevice.getHwInfo().hasSoftwarePhantom();
733 case eHIF_OpticalInterface:
734 return m_ParentDevice.getHwInfo().hasOpticalInterface();
735 case eHIF_PlaybackRouting:
736 return m_ParentDevice.getHwInfo().hasPlaybackRouting();
737 default:
738 debugError("Bogus field\n");
739 return 0;
743 void HwInfoControl::show()
745 debugOutput(DEBUG_LEVEL_NORMAL, "HwInfoControl\n");
749 // control to save settings
750 MultiControl::MultiControl(FireWorks::Device& p, enum eType t)
751 : Control::Discrete(&p, "MultiControl")
752 , m_ParentDevice(p)
753 , m_Type(t)
757 MultiControl::MultiControl(FireWorks::Device& p,
758 enum eType t, std::string n)
759 : Control::Discrete(&p, n)
760 , m_ParentDevice(p)
761 , m_Type(t)
765 MultiControl::~MultiControl()
769 bool MultiControl::setValue(const int v)
771 switch(m_Type) {
772 case eT_SaveSession:
773 debugOutput(DEBUG_LEVEL_VERBOSE, "saving session\n");
774 return m_ParentDevice.saveSession();
775 case eT_Identify:
776 debugOutput(DEBUG_LEVEL_VERBOSE, "indentify device\n");
778 EfcIdentifyCmd cmd;
779 if (!m_ParentDevice.doEfcOverAVC(cmd))
781 debugError("Cmd failed\n");
782 return false;
785 return true;
786 default:
787 debugError("Bad type\n");
788 return false;
792 void MultiControl::show()
794 debugOutput(DEBUG_LEVEL_NORMAL, "MultiControl\n");
795 switch(m_Type) {
796 case eT_SaveSession:
797 debugOutput(DEBUG_LEVEL_NORMAL, "Type: SaveSession\n");
798 break;
799 case eT_Identify:
800 debugOutput(DEBUG_LEVEL_NORMAL, "Type: Identify\n");
801 break;
802 default:
803 debugError("Bad type\n");
807 } // FireWorks