root/trunk/libffado/src/dice/focusrite/saffire_pro26.cpp

Revision 2691, 17.9 kB (checked in by jwoithe, 7 years ago)

Initial attempt to address deprecation of auto_ptr.

C++11 deprecates auto_ptr, and gcc6 (and later versions) print compile time
warnings to this effect whenever it is encountered in the source. The
replacement type is either shared_ptr or unique_ptr depending on the usage.
For almost all usages within FFADO it seems unique_ptr could be the
appropriate choice, but the symantics are a little different to auto_ptr.
Shared_ptr on the other hand can be a drop-in replacement, although it comes
with considerable overheads which unique_ptr avoids. In the context of the
current usage, the extra overhead incurred is not critical.

The code-base cannot at this time change unconditionally to shared_ptr and
unique_ptr because these are not available in gcc4 unless "--std=c++11" is
given. When gcc4 is used certain older versions of dependent libraries must
be used and these in turn will cause compile failures in their header files
if "--std=c++11" is used (libxml++ being an example). At present there are
sufficient users of FFADO still on gcc4 to justify maintaining compatibility
with that gcc version.

The approach adopted at present is to define ffado_smartptr to be either
auto_ptr (if c++11 is not in use) or shared_ptr if it is. All auto_ptr
instances are then changed to ffado_smartptr. This should allow FFADO to be
compiled without errors or warnings on systems using gcc4 and above. Gcc6
defaults to the c++14 standard, so ffado_smartptr will be shared_ptr in that
case; thus the warnings will be avoided.

In time, once gcc4 drops out of common use, the ffado_smartptr instances can
be progressively migrated to unique_ptr or shared_ptr as is appropriate. It
has been pointed out in the ffado-devel mailing list by Jano Svitok (2 May
2017, subject "smart pointers Was: [FFADO-devel] Liquid Saffire 56") that
bebob_dl_mgr.cpp could use unique_ptr. shared_ptr should be ok in other
auto_ptr sites, but futher analysis may show that at least some of them can
use unique_ptr.

The addressing of the auto_ptr issue was prompted by Xavier Forestier's
patch set submitted to ffado-devel in November 2016.

Line 
1 /*
2  * Copyright (C) 2009 by Pieter Palmers
3  * Copyright (C) 2009 by Arnold Krille
4  * Copyright (C) 2015 by Hector Martin
5  *
6  * This file is part of FFADO
7  * FFADO = Free Firewire (pro-)audio drivers for linux
8  *
9  * FFADO is based upon FreeBoB.
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 2 of the License, or
14  * (at your option) version 3 of the License.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25
26 #include "saffire_pro26.h"
27 #include "focusrite_eap.h"
28
29 #include "libutil/ByteSwap.h"
30 #include <cstdio>
31
32 namespace Dice {
33 namespace Focusrite {
34
35 void SaffirePro26::SaffirePro26EAP::setupSources_low() {
36     addSource("SPDIF/In",  4,  4, eRS_AES, 1);
37     addSource("ADAT/In",   8,  8, eRS_ADAT, 1);
38     addSource("Anlg/In", 0,  6, eRS_InS0, 1);
39     addSource("Mixer/Out",  0, 16, eRS_Mixer, 1);
40     addSource("1394/In",   0,  8, eRS_ARX0, 1);
41     addSource("Mute",   0,  1, eRS_Muted);
42 }
43 void SaffirePro26::SaffirePro26EAP::setupDestinations_low() {
44     addDestination("SPDIF/Out",  6,  2, eRD_AES, 1);
45     addDestination("Line/Out", 0,  6, eRD_InS0, 1);
46     addDestination("Mixer/In",  0, 16, eRD_Mixer0, 1);
47     addDestination("Mixer/In",  0,  2, eRD_Mixer1, 17);
48     addDestination("1394/Out",   0, 10, eRD_ATX0, 1);
49     addDestination("1394/Out",   0, 8, eRD_ATX1, 11);
50 // Is a Mute destination useful ?
51 //    addDestination("Mute",   0,  1, eRD_Muted);
52 }
53
54 void SaffirePro26::SaffirePro26EAP::setupSources_mid() {
55     addSource("SPDIF/In",  4,  4, eRS_AES, 1);
56     addSource("ADAT/In",   0,  4, eRS_ADAT, 1);
57     addSource("Anlg/In", 0,  6, eRS_InS0, 1);
58     addSource("Mixer/Out",  0, 16, eRS_Mixer, 1);
59     addSource("1394/In",   0,  8, eRS_ARX0, 1);
60     addSource("Mute",   0,  1, eRS_Muted);
61 }
62 void SaffirePro26::SaffirePro26EAP::setupDestinations_mid() {
63     addDestination("SPDIF/Out",  6,  2, eRD_AES, 1);
64     addDestination("Line/Out", 0,  6, eRD_InS0, 1);
65     addDestination("Mixer/In",  0, 16, eRD_Mixer0, 1);
66     addDestination("Mixer/In",  0,  2, eRD_Mixer1, 17);
67     addDestination("1394/Out",   0, 10, eRD_ATX0, 1);
68     addDestination("1394/Out",   0, 4, eRD_ATX1, 11);
69 // Is a Mute destination useful ?
70 //    addDestination("Mute",   0,  1, eRD_Muted);
71 }
72
73 void SaffirePro26::SaffirePro26EAP::setupSources_high() {
74     printMessage("High (192 kHz) sample rate not supported by Saffire Pro 26\n");
75 }
76
77 void SaffirePro26::SaffirePro26EAP::setupDestinations_high() {
78     printMessage("High (192 kHz) sample rate not supported by Saffire Pro 26\n");
79 }
80
81 /**
82  * The default configurations for the Saffire Pro 26 router.
83  *  For coherence with hardware, destinations must follow a specific ordering
84  *  Front LEDs are connected to the first six eRD_ATX0 entries
85  */
86 void
87 SaffirePro26::SaffirePro26EAP::setupDefaultRouterConfig_low() {
88     unsigned int i;
89     // the 1394 stream receivers except the two "loops" one
90     for (i=0; i<6; i++) {
91         addRoute(eRS_InS0, i, eRD_ATX0, i);
92     }
93     for (i=0; i<2; i++) {
94         addRoute(eRS_AES, i+4, eRD_ATX0, i+6);
95     }
96     for (i=0; i<8; i++) {
97         addRoute(eRS_ADAT, i, eRD_ATX1, i);
98     }
99     // The audio ports
100     // Ensure that audio port are not muted
101     for (i=0; i<6; i++) {
102         addRoute(eRS_ARX0, i%2, eRD_InS0, i);
103     }
104     // the SPDIF receiver
105     for (i=0; i<2; i++) {
106         addRoute(eRS_Muted, 0, eRD_AES, i+6);
107     }
108     // the "loops" 1394 stream receivers
109     for (i=0; i<2; i++) {
110         addRoute(eRS_Muted, 0, eRD_ATX0, i+8);
111     }
112     // the Mixer inputs
113     for (i=0; i<6; i++) {
114         addRoute(eRS_InS0, i, eRD_Mixer0, i);
115     }
116     for (i=0; i<2; i++) {
117         addRoute(eRS_AES, i+4, eRD_Mixer0, i+6);
118     }
119     for (i=0; i<8; i++) {
120         addRoute(eRS_ADAT, i, eRD_Mixer0, i+8);
121     }
122     for (i=0; i<2; i++) {
123         addRoute(eRS_ARX0, i, eRD_Mixer1, i);
124     }
125     // The two mute destinations
126     // FIXME: does this do anything useful?
127     for (i=0; i<2; i++) {
128         addRoute(eRS_Mixer, i, eRD_Muted, 0);
129     }
130 }
131
132 /**
133  *  There must be 40 (?) destinations at mid samplerate
134  *  Front LEDs are connected to the first six eRD_ATX0 entries
135  */
136 void
137 SaffirePro26::SaffirePro26EAP::setupDefaultRouterConfig_mid() {
138     unsigned int i;
139     // the 1394 stream receivers except the two "loops" one
140     for (i=0; i<6; i++) {
141         addRoute(eRS_InS0, i, eRD_ATX0, i);
142     }
143     for (i=0; i<2; i++) {
144         addRoute(eRS_AES, i+4, eRD_ATX0, i+6);
145     }
146     for (i=0; i<4; i++) {
147         addRoute(eRS_ADAT, i, eRD_ATX1, i);
148     }
149     // The audio ports
150     // Ensure that audio port are not muted
151     for (i=0; i<6; i++) {
152         addRoute(eRS_ARX0, i%2, eRD_InS0, i);
153     }
154     // the SPDIF receiver
155     for (i=0; i<2; i++) {
156         addRoute(eRS_Muted, 0, eRD_AES, i+6);
157     }
158     // the "loops" 1394 stream receivers
159     for (i=0; i<2; i++) {
160         addRoute(eRS_Muted, 0, eRD_ATX0, i+8);
161     }
162     // the Mixer inputs
163     for (i=0; i<6; i++) {
164         addRoute(eRS_InS0, i, eRD_Mixer0, i);
165     }
166     for (i=0; i<2; i++) {
167         addRoute(eRS_AES, i+4, eRD_Mixer0, i+6);
168     }
169     for (i=0; i<4; i++) {
170         addRoute(eRS_ADAT, i, eRD_Mixer0, i+8);
171     }
172     for (i=0; i<4; i++) {
173         addRoute(eRS_Muted, i, eRD_Mixer0, i+12);
174     }
175     for (i=0; i<2; i++) {
176         addRoute(eRS_ARX0, i, eRD_Mixer1, i);
177     }
178     // The two mute destinations
179     // FIXME: does this do anything useful?
180     for (i=0; i<2; i++) {
181         addRoute(eRS_Mixer, i, eRD_Muted, 0);
182     }
183 }
184
185 /**
186  *  High rate not supported
187  */
188 void
189 SaffirePro26::SaffirePro26EAP::setupDefaultRouterConfig_high() {
190     printMessage("High (192 kHz) sample rate not supported by Saffire Pro 26\n");
191 }
192
193 /**
194  *  Pro 24 Monitor section
195  */
196 SaffirePro26::SaffirePro26EAP::MonitorSection::MonitorSection(Dice::Focusrite::FocusriteEAP* eap,
197     std::string name) : Control::Container(eap, name)
198     , m_eap(eap)
199 {
200     // Global Mute control
201     Control::Container* grp_globalmute = new Control::Container(m_eap, "GlobalMute");
202     addElement(grp_globalmute);
203     FocusriteEAP::Switch* mute =
204         new FocusriteEAP::Switch(m_eap, "State",
205                                  SAFFIRE_PRO26_REGISTER_APP_GLOBAL_MUTE_SWITCH,
206                                  FOCUSRITE_EAP_GLOBAL_MUTE_SWITCH_VALUE,
207                                  SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
208                                  SAFFIRE_PRO26_MESSAGE_SET_GLOBAL_DIM_MUTE_SWITCH);
209     grp_globalmute->addElement(mute);
210
211     // Global Dim control
212     Control::Container* grp_globaldim = new Control::Container(m_eap, "GlobalDim");
213     addElement(grp_globaldim);
214     FocusriteEAP::Switch* dim =
215         new FocusriteEAP::Switch(m_eap, "State",
216                                  SAFFIRE_PRO26_REGISTER_APP_GLOBAL_DIM_SWITCH,
217                                  FOCUSRITE_EAP_GLOBAL_DIM_SWITCH_VALUE,
218                                  SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
219                                  SAFFIRE_PRO26_MESSAGE_SET_GLOBAL_DIM_MUTE_SWITCH);
220     grp_globaldim->addElement(dim);
221     FocusriteEAP::Poti* dimlevel =
222         new FocusriteEAP::Poti(m_eap, "Level",
223                                SAFFIRE_PRO26_REGISTER_APP_GLOBAL_DIM_VOLUME,
224                                SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
225                                SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
226     grp_globaldim->addElement(dimlevel);
227
228     // The mono switches don't seem to do anything on this device (and are not
229     // implemented in MixControl)
230
231     // Independent control of each line/out
232     Control::Container* grp_perchannel = new Control::Container(m_eap, "LineOut");
233     addElement(grp_perchannel);
234     FocusriteEAP::VolumeControl* vol;
235
236     // per Line/Out monitoring
237     FocusriteEAP::Switch* s;
238     for (unsigned int i=0; i<SAFFIRE_PRO26_APP_STEREO_LINEOUT_SIZE; ++i) {
239         std::stringstream stream;
240
241         // Activate/Unactivate per Line/Out volume monitoring
242         stream.str(std::string());
243         stream << "UnActivate" << i*2+1;
244         s =
245           new FocusriteEAP::Switch(m_eap, stream.str(),
246                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_SWITCH+i*sizeof(quadlet_t),
247                                    FOCUSRITE_EAP_SWITCH_BIT_1,
248                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
249                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
250         grp_perchannel->addElement(s);
251         stream.str(std::string());
252         stream << "UnActivate" << i*2+2;
253         s =
254           new FocusriteEAP::Switch(m_eap, stream.str(),
255                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_SWITCH+i*sizeof(quadlet_t),
256                                    FOCUSRITE_EAP_SWITCH_BIT_2,
257                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
258                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
259         grp_perchannel->addElement(s);
260
261         // per Line/Out mute/unmute
262         stream.str(std::string());
263         stream << "Mute" << i*2+1;
264         s =
265           new FocusriteEAP::Switch(m_eap, stream.str(),
266                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_SWITCH+i*sizeof(quadlet_t),
267                                    FOCUSRITE_EAP_SWITCH_BIT_3,
268                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
269                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
270         grp_perchannel->addElement(s);
271         stream.str(std::string());
272         stream << "Mute" << i*2+2;
273         s =
274           new FocusriteEAP::Switch(m_eap, stream.str(),
275                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_SWITCH+i*sizeof(quadlet_t),
276                                    FOCUSRITE_EAP_SWITCH_BIT_4,
277                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
278                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
279         grp_perchannel->addElement(s);
280
281         // per Line/Out global mute activation/unactivation
282         stream.str(std::string());
283         stream << "GMute" << 2*i+1;
284         s =
285           new FocusriteEAP::Switch(m_eap, stream.str(),
286                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_SWITCH_CONTROL,
287                                    FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
288                                         <<(FOCUSRITE_EAP_SWITCH_CONTROL_MUTE_SHIFT+2*i),
289                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
290                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_SWITCH_CONTROL);
291         grp_perchannel->addElement(s);
292
293         stream.str(std::string());
294         stream << "GMute" << 2*i+2;
295         s =
296           new FocusriteEAP::Switch(m_eap, stream.str(),
297                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_SWITCH_CONTROL,
298                                    FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
299                                         <<(FOCUSRITE_EAP_SWITCH_CONTROL_MUTE_SHIFT+2*i+1),
300                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
301                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_SWITCH_CONTROL);
302         grp_perchannel->addElement(s);
303
304         // per Line/Out global dim activation/unactivation
305         stream.str(std::string());
306         stream << "GDim" << 2*i+1;
307         s =
308           new FocusriteEAP::Switch(m_eap, stream.str(),
309                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_SWITCH_CONTROL,
310                                    FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
311                                         <<(FOCUSRITE_EAP_SWITCH_CONTROL_DIM_SHIFT+2*i),
312                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
313                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_SWITCH_CONTROL);
314         grp_perchannel->addElement(s);
315
316         stream.str(std::string());
317         stream << "GDim" << 2*i+2;
318         s =
319           new FocusriteEAP::Switch(m_eap, stream.str(),
320                                    SAFFIRE_PRO26_REGISTER_APP_LINEOUT_SWITCH_CONTROL,
321                                    FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
322                                         <<(FOCUSRITE_EAP_SWITCH_CONTROL_DIM_SHIFT+2*i+1),
323                                    SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
324                                    SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_SWITCH_CONTROL);
325         grp_perchannel->addElement(s);
326
327         // per Line/Out volume control
328         stream.str(std::string());
329         stream << "Volume" << i*2+1;
330         vol =
331           new FocusriteEAP::VolumeControl(m_eap, stream.str(),
332                                           SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_VOLUME
333                                               +i*sizeof(quadlet_t),
334                                           FOCUSRITE_EAP_LINEOUT_VOLUME_SET_1,
335                                           SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
336                                           SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
337         grp_perchannel->addElement(vol);
338         stream.str(std::string());
339         stream << "Volume" << i*2+2;
340         vol =
341           new FocusriteEAP::VolumeControl(m_eap, stream.str(),
342                                           SAFFIRE_PRO26_REGISTER_APP_LINEOUT_MONITOR_VOLUME
343                                               +i*sizeof(quadlet_t),
344                                           FOCUSRITE_EAP_LINEOUT_VOLUME_SET_2,
345                                           SAFFIRE_PRO26_REGISTER_APP_MESSAGE_SET,
346                                           SAFFIRE_PRO26_MESSAGE_SET_LINEOUT_MONITOR_VOLUME);
347         grp_perchannel->addElement(vol);
348     }
349
350     // The Saffire PRO 26 does not have line/inst/gain controls. Instead it has
351     // dedicated hardware switches for inputs 1/2, auto selection for inputs 3/4,
352     // and no controls for inputs 5/6.
353
354     // There is also support for ADAT-as-SPDIF, but no control is necessary.
355     // SPDIF inputs appear on their own dedicated routing source when present
356     // (labeled SPDIF 3/4).
357 }
358
359 SaffirePro26::SaffirePro26( DeviceManager& d,
360                             ffado_smartptr<ConfigRom>( configRom ))
361     : Dice::Device(d , configRom)
362 {
363     debugOutput(DEBUG_LEVEL_VERBOSE, "Created Dice::Focusrite::SaffirePro26 (NodeID %d)\n",
364                 getConfigRom().getNodeId());
365 }
366
367 SaffirePro26::~SaffirePro26()
368 {
369     //debugOutput(DEBUG_LEVEL_VERBOSE, "Deleting the saffirePro26\n");
370     /// I wonder whether we should really save only on clean exits or also each time a setting is
371     //  changed. Or should we provide a function (and thus gui-button) to save the state of the
372     //  device?
373     getEAP()->storeFlashConfig();
374 }
375
376 bool SaffirePro26::discover() {
377     if (Dice::Device::discover()) {
378         fb_quadlet_t* version = (fb_quadlet_t *)calloc(2, sizeof(fb_quadlet_t));
379         getEAP()->readRegBlock(Dice::EAP::eRT_Application, SAFFIRE_PRO26_REGISTER_APP_VERSION, version, 1*sizeof(fb_quadlet_t));
380         // Only known firmware for Saffire Pro 26 devices so far is 0x10000.
381         if (version[0] != 0x10000) {
382             fprintf(stderr, "This is a Focusrite Saffire Pro26 but not the right firmware. Better stop here before something goes wrong.\n");
383             fprintf(stderr, "This device has firmware 0x%x while we only know about version 0x%x.\n", version[0], 0x10000);
384             return false;
385         }
386
387         // FIXME: What is the purpose of the following commented lines at this point ?
388         //getEAP()->readRegBlock(Dice::EAP::eRT_Command, 0x00, tmp, 2*sizeof(fb_quadlet_t)); // DEBUG
389         //hexDumpQuadlets(tmp, 2); // DEBUG
390
391         FocusriteEAP* eap = dynamic_cast<FocusriteEAP*>(getEAP());
392         SaffirePro26EAP::MonitorSection* monitor = new SaffirePro26EAP::MonitorSection(eap, "Monitoring");
393         getEAP()->addElement(monitor);
394         return true;
395     }
396     return false;
397 }
398
399 void SaffirePro26::showDevice()
400 {
401     debugOutput(DEBUG_LEVEL_VERBOSE, "This is a Dice::Focusrite::SaffirePro26\n");
402     Dice::Device::showDevice();
403 }
404 Dice::EAP* SaffirePro26::createEAP() {
405     return new SaffirePro26EAP(*this);
406 }
407
408 bool SaffirePro26::setNickname( std::string name ) {
409     char nickname[SAFFIRE_PRO26_APP_NICK_NAME_SIZE+1];
410
411     // The device has room for SAFFIRE_PRO26_APP_NICK_NAME_SIZE characters.
412     // Erase supplementary characters or fill-in with NULL character if necessary
413     strncpy(nickname, name.c_str(), SAFFIRE_PRO26_APP_NICK_NAME_SIZE);
414
415     // Strings from the device are always little-endian,
416     // so byteswap for big-endian machines
417     #if __BYTE_ORDER == __BIG_ENDIAN
418     byteSwapBlock((quadlet_t *)nickname, SAFFIRE_PRO26_APP_NICK_NAME_SIZE/4);
419     #endif
420
421     if (!getEAP()->writeRegBlock(Dice::EAP::eRT_Application, SAFFIRE_PRO26_REGISTER_APP_NICK_NAME,
422                                  (quadlet_t*)nickname, SAFFIRE_PRO26_APP_NICK_NAME_SIZE)) {
423         debugError("Could not write nickname string \n");
424         return false;
425     }
426     return true;
427 }
428
429 std::string SaffirePro26::getNickname() {
430     char nickname[SAFFIRE_PRO26_APP_NICK_NAME_SIZE+1];
431     if (!getEAP()->readRegBlock(Dice::EAP::eRT_Application, SAFFIRE_PRO26_REGISTER_APP_NICK_NAME,
432                                 (quadlet_t*)nickname, SAFFIRE_PRO26_APP_NICK_NAME_SIZE)){
433         debugError("Could not read nickname string \n");
434         return std::string("(unknown)");
435     }
436
437     // Strings from the device are always little-endian,
438     // so byteswap for big-endian machines
439     #if __BYTE_ORDER == __BIG_ENDIAN
440     byteSwapBlock((quadlet_t *)nickname, SAFFIRE_PRO26_APP_NICK_NAME_SIZE/4);
441     #endif
442
443     // The device supplies at most SAFFIRE_PRO26_APP_NICK_NAME_SIZE characters.  Ensure the string is
444     // NULL terminated.
445     nickname[SAFFIRE_PRO26_APP_NICK_NAME_SIZE] = 0;
446     return std::string(nickname);
447 }
448
449 }
450 }
451
452 // vim: et
Note: See TracBrowser for help on using the browser.