Subversion Repositories tpanel

Rev

Rev 482 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
446 andreas 1
/*
2
 * Copyright (C) 2020 to 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <fstream>
20
#include <vector>
21
#include <iterator>
22
#include <map>
23
#include <unistd.h>
24
#include <sys/stat.h>
25
#include <sys/types.h>
26
#ifdef __ANDROID__
27
#include <QUuid>
28
#include <android/log.h>
29
#include "tvalidatefile.h"
30
#include "tvalidatefile.h"
31
#else
32
#include <uuid/uuid.h>
33
#endif
34
#include "ttpinit.h"
35
#include "tconfig.h"
36
#include "terror.h"
37
#include "tresources.h"
38
#include "tlock.h"
39
#ifdef __APPLE__
40
#include <TargetConditionals.h>
41
#if TARGET_OS_SIMULATOR || TARGET_OS_IOS
42
#include <QString>
43
#include "ios/QASettings.h"
44
#endif
45
#endif
46
 
47
#if __cplusplus < 201402L
48
#   error "This module requires at least C++14 standard!"
49
#else   // __cplusplus < 201402L
50
#   if __cplusplus < 201703L
51
#       include <experimental/filesystem>
52
namespace fs = std::experimental::filesystem;
53
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
54
#   else    // __cplusplus < 201703L
55
#       include <filesystem>
56
#       ifdef __ANDROID__
57
namespace fs = std::__fs::filesystem;
58
#       else    // __ANDROID__
59
namespace fs = std::filesystem;
60
#       endif   // __ANDROID__
61
#   endif   // __cplusplus < 201703L
62
#endif  // __cplusplus < 201402L
63
 
64
using std::string;
65
using std::ifstream;
66
using std::ofstream;
67
using std::fstream;
68
using std::vector;
69
using std::map;
70
using std::pair;
71
using std::cout;
72
using std::cerr;
73
using std::endl;
74
 
75
bool TConfig::mInitialized{false};
76
int TConfig::mChannel{0};
77
bool TConfig::mMute{false};
78
bool TConfig::mTemporary{false};
79
bool TConfig::mLogFileEnabled{false};
80
std::mutex config_mutex;
81
 
480 andreas 82
typedef struct _APPS_t
83
{
84
    string appID;       // Name corresponding to G5 apps table
85
    string path;        // Path and name of the application
86
}_APPS_t;
87
 
446 andreas 88
/**
89
 * @struct SETTINGS
90
 * @brief The SETTINGS struct bundles the configuration options.
91
 *
92
 * This structure contains variables for all possible configuration options.
93
 * It is used by the class TConfig. Through this class it's possible to
94
 * access all configuration options.
95
 */
96
struct SETTINGS
97
{
98
    string pname{"tpanel"};     //!< Name of the program (default "tpanel")
99
    string path;                //!< The path where the configuration file is located
100
    string name;                //!< The name of the configuration file
101
    string project;             //!< The path where the original project files are located
102
    string server;              //!< The name or IP address of the server to connect
103
    int system{0};              //!< The number of the AMX system
104
    int port{0};                //!< The port number
105
    int ID{0};                  //!< the panel ID (a number starting by 10000)
106
    string ptype;               //!< The type of the panel (android, ipad, iphone, ...)
107
    string version;             //!< The "firmware" version
108
    string logFile;             //!< Optional path and name of a logfile
109
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
110
#ifdef QT_DEBUG
111
    string logLevel{"INFO|WARNING|ERROR|DEBUG"};   //!< The log level(s).
112
    uint logLevelBits{HLOG_INFO|HLOG_WARNING|HLOG_ERROR|HLOG_DEBUG};//!< The numeric bit field of the loglevel
480 andreas 113
#else   // QT_DEBUG
446 andreas 114
    string logLevel{"NONE"};   //!< The log level(s).
115
    uint logLevelBits{HLOG_NONE};//!< The numeric bit field of the loglevel
480 andreas 116
#endif  // QT_DEBUG
446 andreas 117
#else
118
    string logLevel{"PROTOCOL"};//!< The log level(s).
119
    uint logLevelBits{HLOG_PROTOCOL};//!< The numeric bit field of the loglevel
480 andreas 120
    vector<_APPS_t> apps;
446 andreas 121
#endif
122
    bool longformat{false};     //!< TRUE = long format
123
    bool noBanner{false};       //!< Startup without showing a banner on the command line.
124
    bool certCheck{false};      //!< TRUE = Check certificate for SSL connection
125
    bool scale{false};          //!< TRUE = Images are scaled to fit the whole screen
126
    bool tbsuppress{false};     //!< TRUE = Don't show toolbar even if enough space
127
    bool tbforce{true};         //!< Only if "tbsuppress" = FALSE: TRUE = The toolbar is forced to display, FALSE = The toolbar is only visible if there is enough space left
128
    bool profiling{false};      //!< TRUE = The declaration traces meassure the time and write it to the log
129
    size_t max_cache{100};      //!< Size of internal button cache in Mb
130
    string password1;           //!< First panel password
131
    string password2;           //!< Second panel password
132
    string password3;           //!< Third panel password
133
    string password4;           //!< Fourth panel password
134
    bool systemRotationFix{false};  //!< TRUE = Rotation is blocked and orientation sensor is ignored.
135
    string uuid;                //!< An UUID set automatically after first start.
136
    // FTP credentials
137
    string ftpUser;             //!< The username for FTP of the controller (default: administrator)
138
    string ftpPassword;         //!< The password for FTP of the controller (default: password)
139
    string ftpSurface;          //!< The name of the file containing the TPDesign4 file to load
140
    bool ftpPassive{true};      //!< If false the data port 20 is used for file transfer
141
    time_t ftpLastDownload{0};  //!< The timestamp of the last download
142
    // SIP settings
143
    string sip_proxy;           //!< The address of the SIP proxy
144
    int sip_port{5060};         //!< Initializes the port of the SIP proxy to 5060
145
    int sip_portTLS{0};         //!< Initializes the TLS port of the SIP proxy to 0 (not used by default)
146
    string sip_stun;            //!< STUN address
147
    string sip_domain;          //!< Local domain
148
    string sip_user;            //!< The SIP user to connect.
149
    string sip_password;        //!< The SIP password to connect. Note: This password is saved in plain text!
150
    bool sip_ipv4{true};        //!< Default: TRUE, Enables or disables IPv4.
151
    bool sip_ipv6{true};        //!< Default: TRUE, Enables or disables IPv6. Has precedence over IPv4.
152
    bool sip_iphone{false};     //!< Default: FALSE, if enabled and SIP is enabled then the internal phone dialog is used.
153
    TConfig::SIP_FIREWALL_t sip_firewall{TConfig::SIP_NO_FIREWALL}; //!< Defines how to deal with a firewall.
154
    bool sip_enabled{false};    //!< By default SIP is disabled
155
    // Sound settings
156
    string systemSound;         //!< name of the set system sound played on every touch.
157
    bool systemSoundState{false};   //!< TRUE = play systemsound on every touch
158
    string systemSingleBeep;    //!< name of the system sound file to play a single beep.
159
    string systemDoubleBeep;    //!< name of the system sound file to play a double beep.
160
    int systemVolume{100};      //!< The set volume to use [0 ... 100]
161
    int systemGain{100};        //!< The set microphone level to use [0 ... 100]
162
};
163
 
164
typedef struct SETTINGS settings_t;
165
static settings_t localSettings;        //!< Global defines settings used in class TConfig.
166
static settings_t localSettings_temp;   //!< Global defines settings temporary settings
167
static map<string, string> userPasswords;
168
static string fileUserPasswords("user_passwords.txt");
169
 
170
/**
171
 * @brief TConfig::TConfig constructor
172
 *
173
 * @param path  A path and name of a configuration file.
174
 */
175
TConfig::TConfig(const std::string& path)
176
    : mPath(path)
177
{
178
#if TARGET_OS_IOS == 0 && TARGET_OS_SIMULATOR == 0
179
    // Initialize the possible configuration paths
180
    mCfgPaths.push_back("/etc");
181
    mCfgPaths.push_back("/etc/tpanel");
182
    mCfgPaths.push_back("/usr/etc");
183
    mCfgPaths.push_back("/usr/etc/tpanel");
184
#ifdef __APPLE__
185
    mCfgPaths.push_back("/opt/local/etc");
186
    mCfgPaths.push_back("/opt/local/etc/tpanel");
187
    mCfgPaths.push_back("/opt/local/usr/etc");
188
    mCfgPaths.push_back("/opt/local/usr/etc/tpanel");
189
#endif
190
    if (findConfig())
191
        readConfig();
192
 
193
    readUserPasswords();
194
#else
195
    readConfig();
196
    readUserPasswords();
197
#endif
198
}
199
 
200
/**
201
 * Simple method to read the configuration again. This is usefull if, for
202
 * example the configuration options changed but should not be saved. Instead
203
 * they were canceled and therefor the options are read again from file.
204
 *
205
 * @return On success it returns TRUE.
206
 */
207
bool TConfig::reReadConfig()
208
{
209
    return readConfig();
210
}
211
 
212
/**
213
 * @brief TConfig::setTemporary - Activate/deactivate temporary config
214
 * Activates or deactivates the state of the temporary configuration. The
215
 * temporary configuration is a shadow configuration which holds all changes
216
 * to the configuration without saving it.
217
 *
218
 * @param tmp   State of the active configuration.
219
 * @return
220
 * Returns the previous state of the configuration setting.
221
 */
222
bool TConfig::setTemporary(bool tmp)
223
{
224
    DECL_TRACER("TConfig::setTemporary(bool tmp)");
225
 
226
    bool old = mTemporary;
227
    mTemporary = tmp;
228
    return old;
229
}
230
 
231
void TConfig::reset()
232
{
233
    DECL_TRACER("TConfig::reset()");
234
 
235
    localSettings_temp = localSettings;
236
    mTemporary = false;
237
}
238
 
239
/**
240
 * @brief TConfig::setProgName Sets the name of the application.
241
 * @param pname The name of the application.
242
 */
243
void TConfig::setProgName(const std::string& pname)
244
{
245
    if (mTemporary)
246
        localSettings_temp.pname = pname;
247
    else
248
        localSettings.pname = pname;
249
 
250
    mTemporary = false;
251
}
252
 
253
/**
254
 * @brief TConfig::getProgName Retrieves the prevously stored application name.
255
 * @return The name of this application.
256
 */
257
std::string & TConfig::getProgName()
258
{
259
    return mTemporary ? localSettings_temp.pname : localSettings.pname;
260
}
261
 
262
/**
263
 * @brief TConfig::getChannel returns the AMX channel to use.
264
 *
265
 * The AMX channels an AMX panel can use start at 10000. This method returns
266
 * the channel number found in the configuration file. If there was no
267
 * channel defination found, it returns the default channel 10001.
268
 *
269
 * @return The AMX channel number to use.
270
 */
271
int TConfig::getChannel()
272
{
273
    DECL_TRACER("TConfig::getChannel()");
274
 
275
    int ID = mTemporary ? localSettings_temp.ID : localSettings.ID;
276
 
277
    if (mChannel > 0 && mChannel != ID)
278
        return mChannel;
279
 
280
    return ID;
281
}
282
 
283
/**
284
 * @brief TConfig::getConfigFileName returns the name of the configuration file.
285
 *
286
 * @return The name of the configuration file.
287
 */
288
std::string& TConfig::getConfigFileName()
289
{
290
    return mTemporary ? localSettings_temp.name : localSettings.name;
291
}
292
 
293
/**
294
 * @brief TConfig::getConfigPath returns the path configuration file.
295
 *
296
 * The path was defined on the command line or found by searching the standard
297
 * directories.
298
 *
299
 * @return The path of the configuration file.
300
 */
301
std::string& TConfig::getConfigPath()
302
{
303
    return mTemporary ? localSettings_temp.path : localSettings.path;
304
}
305
 
306
/**
307
 * @brief TConfig::getController returns the network name or IP address of the AMX controller.
308
 *
309
 * The network name or the IP address was read from the configuration file.
310
 *
311
 * @return The network name of the AMX controller.
312
 */
313
std::string& TConfig::getController()
314
{
315
    DECL_TRACER("TConfig::getController()");
316
 
317
    return mTemporary ? localSettings_temp.server : localSettings.server;
318
}
319
 
320
/**
321
 * @brief TConfig::getSystem return the AMX system number.
322
 *
323
 * This number was read from the configuration file. If there was no system
324
 * number defined in the configuration file, then the default number 0 is
325
 * returned.
326
 *
327
 * @return The AMX system number.
328
 */
329
int TConfig::getSystem()
330
{
331
    DECL_TRACER("TConfig::getSystem()");
332
 
333
    return mTemporary ? localSettings_temp.system :  localSettings.system;
334
}
335
 
336
/**
337
 * @brief TConfig::getFirmVersion returns the version of the firmware.
338
 *
339
 * This option was read from the configuration file. There can be any version
340
 * number defined. But you must keep in mind, that the AMX controller may not
341
 * accept any number. If there was no version number defined, the standard
342
 * version number 1.0 is returned.
343
 *
344
 * @return The firmware version of this panel.
345
 */
346
std::string& TConfig::getFirmVersion()
347
{
348
    DECL_TRACER("TConfig::getFirmVersion()");
349
 
350
    return mTemporary ? localSettings_temp.version : localSettings.version;
351
}
352
 
353
/**
354
 * @brief TConfig::getLogFile the path and name of a logfile.
355
 *
356
 * If there is a logfile name defined in the configuration file, it is used
357
 * to write messages there. It depends on the _log level_ what is logged.
358
 *
359
 * @return The path and name of a logfile.
360
 */
361
std::string& TConfig::getLogFile()
362
{
484 andreas 363
    cerr << "TRACE: TConfig::getLogFile()"  << endl;
446 andreas 364
    return mTemporary ? localSettings_temp.logFile : localSettings.logFile;
365
}
366
 
367
/**
368
 * @brief TConfig::getLogLevel returns the defined log level.
369
 *
370
 * The loglevel can consist of the following values:
371
 *
372
 *     NONE         Logs nothing (default for Android)
373
 *     INFO         Logs only informations
374
 *     WARNING      Logs only warnings
375
 *     ERROR        Logs only errors
376
 *     TRACE        Logs only trace messages
377
 *     DEBUG        Logs only debug messages
378
 *     PROTOCOL     Logs only INFO and ERROR (default if NOT Android)
379
 *     ALL          Logs everything
380
 *
381
 * All log levels can be combined by concatenating them with the | symbol.
382
 *
383
 * @return The log level(s) as a string.
384
 */
385
string& TConfig::getLogLevel()
386
{
484 andreas 387
    cerr << "TRACE: TConfig::getLogLevel()" << endl;
446 andreas 388
    return mTemporary ? localSettings_temp.logLevel : localSettings.logLevel;
389
}
390
 
391
/**
392
 * @brief TConfig::getLogLevelBits
393
 *
394
 * Returns the raw bit field defining the loglevels selected.
395
 *
396
 * @return The bit field of representing the selected log levels.
397
 */
398
uint TConfig::getLogLevelBits()
399
{
400
    DECL_TRACER("TConfig::getLogLevelBits()");
401
 
402
    return mTemporary ? localSettings_temp.logLevelBits : localSettings.logLevelBits;
403
}
404
/**
405
 * @brief TConfig::getPanelType the AMX type name of the panel.
406
 *
407
 * The type name of the panel is defined in the configuration file. If this
408
 * option was not defined, the default panel _android_ is returned.
409
 *
410
 * @return The type name of the panel.
411
 */
412
std::string& TConfig::getPanelType()
413
{
414
    DECL_TRACER("TConfig::getPanelType()");
415
 
416
    return mTemporary ? localSettings_temp.ptype : localSettings.ptype;
417
}
418
 
419
/**
420
 * @brief TConfig::getPort returnes the AMX port number to connect to.
421
 *
422
 * The port number can be defined in the configuration file. If there is no
423
 * configuration the default number 1319 is returned.
424
 *
425
 * @return The AMX network port number.
426
 */
427
int TConfig::getPort()
428
{
429
    DECL_TRACER("TConfig::getPort()");
430
 
431
    return mTemporary ? localSettings_temp.port : localSettings.port;
432
}
433
 
434
/**
435
 * @brief TConfig::getProjectPath returns the path to the AMX configuration files.
436
 *
437
 * The path was read from the configuration file. This path contains all the
438
 * files needed to display the elements of the surface.
439
 *
440
 * @return The path to the AMX configuration files.
441
 */
442
string& TConfig::getProjectPath()
443
{
444
    return localSettings.project;
445
}
446
 
447
/**
448
 * @brief TConfig::getSystemProjectPath returns the path to the AMX setup
449
 * configuration files.
450
 *
451
 * The path was read from the configuration file. This path contains all the
452
 * files needed to display the setup elements of the setup dialog.
453
 *
454
 * @return The path to the AMX setup configuration files.
455
 */
456
string TConfig::getSystemProjectPath()
457
{
458
    return localSettings.project + "/__system";
459
}
460
 
461
string TConfig::getSystemPath(SYSTEMRESOURCE_t sres)
462
{
463
    DECL_TRACER("TConfig::getSystemPath(SYSTEMRESOURCE_t sres)");
464
 
465
    string p;
466
 
467
    switch(sres)
468
    {
469
        case BORDERS:   p = "/borders"; break;
470
        case FONTS:     p = "/fonts"; break;
471
        case IMAGES:    p = "/images"; break;
472
        case SLIDERS:   p = "/sliders"; break;
473
        case SOUNDS:    p = "/sounds"; break;
474
        default:
475
            p.clear();
476
    }
477
 
478
    return localSettings.project + "/__system/graphics" + p;
479
}
480
 
481
bool TConfig::saveLogFile(const string &file)
482
{
483
    DECL_TRACER("TConfig::saveLogFile(const string &file)");
484
 
485
    string logFile = mTemporary ? localSettings_temp.logFile : localSettings.logFile;
486
 
487
    if (file.empty() || logFile.compare(file) == 0)
488
        return false;
489
 
490
    if (mTemporary)
491
        localSettings_temp.logFile = file;
492
    else
493
    {
494
        localSettings.logFile = file;
495
#ifdef __ANDROID__
496
        if (mLogFileEnabled)
497
            TStreamError::setLogFile(file);
498
        else
499
            TStreamError::setLogFile("");
500
#else
501
        TStreamError::setLogFile(file);
502
#endif
503
    }
504
 
505
    mTemporary = false;
506
    return true;
507
}
508
 
509
bool TConfig::saveLogLevel(const string &level)
510
{
511
    DECL_TRACER("TConfig::saveLogLevel(const string &level)");
512
 
513
    if (level.find(SLOG_NONE) == string::npos && level.find(SLOG_INFO) == string::npos && level.find(SLOG_WARNING) == string::npos &&
514
            level.find(SLOG_ERROR) == string::npos && level.find(SLOG_TRACE) == string::npos && level.find(SLOG_DEBUG) == string::npos &&
515
            level.find(SLOG_PROTOCOL) == string::npos && level.find(SLOG_ALL) == string::npos)
516
        return false;
517
 
518
    if (mTemporary)
519
    {
520
        localSettings_temp.logLevel = level;
521
        localSettings_temp.logLevelBits = logLevelStrToBits(level);
522
    }
523
    else
524
    {
525
        localSettings.logLevel = level;
526
        localSettings.logLevelBits = logLevelStrToBits(level);
527
    }
528
 
529
    MSG_INFO("New log level: " << level);
530
    mTemporary = false;
531
    return true;
532
}
533
 
534
bool TConfig::saveLogLevel(uint level)
535
{
536
    DECL_TRACER("TConfig::saveLogLevel(uint level)");
537
 
538
    if (level != 0 && !(level&HLOG_INFO) && !(level&HLOG_WARNING) &&
539
            !(level&HLOG_ERROR) && !(level&HLOG_TRACE) && !(level&HLOG_DEBUG))
540
        return false;
541
 
542
    if (mTemporary)
543
    {
544
        localSettings_temp.logLevelBits = level;
545
        localSettings_temp.logLevel = logLevelBitsToString(level);
546
    }
547
    else
548
    {
549
        localSettings.logLevelBits = level;
550
        localSettings.logLevel = logLevelBitsToString(level);
551
        TStreamError::setLogLevel(level);
552
        MSG_INFO("New log level from bits: " << localSettings.logLevel);
553
    }
554
 
555
    mTemporary = false;
556
    return true;
557
}
558
 
559
bool TConfig::saveChannel(int channel)
560
{
561
    DECL_TRACER("TConfig::saveChannel(int channel)");
562
 
563
    if (channel < 10000 || channel > 20000)
564
        return false;
565
 
566
    if (mTemporary)
567
        localSettings_temp.ID = channel;
568
    else
569
        localSettings.ID = channel;
570
 
571
    mTemporary = false;
572
    return true;
573
}
574
 
575
bool TConfig::saveController(const string &cnt)
576
{
577
    DECL_TRACER("TConfig::saveController(const string &cnt)");
578
 
579
    if (mTemporary)
580
        localSettings_temp.server = cnt;
581
    else
582
        localSettings.server = cnt;
583
 
584
    mTemporary = false;
585
    return true;
586
}
587
 
588
bool TConfig::savePanelType(const string &pt)
589
{
590
    DECL_TRACER("TConfig::savePanelType(const string &pt)");
591
 
592
    if (mTemporary)
593
        localSettings_temp.ptype = pt;
594
    else
595
        localSettings.ptype = pt;
596
 
597
    mTemporary = false;
598
    return true;
599
}
600
 
601
bool TConfig::savePort(int port)
602
{
603
    DECL_TRACER("TConfig::savePort(int port)");
604
 
605
    if (port < 1024 || port > 32767)
606
        return false;
607
 
608
    if (mTemporary)
609
        localSettings_temp.port = port;
610
    else
611
        localSettings.port = port;
612
 
613
    mTemporary = false;
614
    return true;
615
}
616
 
617
bool TConfig::saveProjectPath(const string &path)
618
{
619
    DECL_TRACER("TConfig::saveProjectPath(const string &path)");
620
 
621
    if (path.empty())
622
        return false;
623
 
624
    if (mTemporary)
625
        localSettings_temp.project = path;
626
    else
627
        localSettings.project = path;
628
 
629
    mTemporary = false;
630
    return true;
631
}
632
 
633
void TConfig::saveFormat(bool format)
634
{
635
    DECL_TRACER(string("TConfig::saveFormat(bool format) ") + (format ? "[TRUE]" : "[FALSE]"));
636
 
637
    if (mTemporary)
638
        localSettings_temp.longformat = format;
639
    else
640
        localSettings.longformat = format;
641
 
642
    mTemporary = false;
643
}
644
 
645
void TConfig::saveScale(bool scale)
646
{
647
    DECL_TRACER("TConfig::saveScale(bool scale)");
648
 
649
    if (mTemporary)
650
        localSettings_temp.scale = scale;
651
    else
652
        localSettings.scale = scale;
653
 
654
    mTemporary = false;
655
}
656
 
657
void TConfig::saveBanner(bool banner)
658
{
659
    DECL_TRACER("TConfig::saveBanner(bool banner)");
660
 
661
    if (mTemporary)
662
        localSettings_temp.noBanner = banner;
663
    else
664
        localSettings.noBanner = banner;
665
 
666
    mTemporary = false;
667
}
668
 
669
void TConfig::saveToolbarForce(bool tb)
670
{
671
    DECL_TRACER("TConfig::saveToolbarForce(bool tb)");
672
 
673
    if (mTemporary)
674
        localSettings_temp.tbforce = tb;
675
    else
676
        localSettings.tbforce = tb;
677
 
678
    mTemporary = false;
679
}
680
 
681
void TConfig::saveToolbarSuppress(bool tb)
682
{
683
    DECL_TRACER("TConfig::saveToolbarSuppress(bool tb)");
684
 
685
    if (mTemporary)
686
        localSettings_temp.tbsuppress = tb;
687
    else
688
        localSettings.tbsuppress = tb;
689
 
690
    mTemporary = false;
691
}
692
 
693
void TConfig::saveProfiling(bool prof)
694
{
695
    DECL_TRACER("TConfig::saveProfiling(bool prof)");
696
 
697
    if (mTemporary)
698
        localSettings_temp.profiling = prof;
699
    else
700
        localSettings.profiling = prof;
701
 
702
    mTemporary = false;
703
}
704
 
705
void TConfig::saveButtonCache(size_t size)
706
{
707
    DECL_TRACER("TConfig::saveButtonCache(size_t size)");
708
 
709
    if (mTemporary)
710
        localSettings_temp.max_cache = size;
711
    else
712
        localSettings.max_cache = size;
713
 
714
    mTemporary = false;
715
}
716
 
717
void TConfig::savePassword1(const std::string& pw)
718
{
719
    DECL_TRACER("TConfig::savePassword1(const std::string& pw)");
720
 
721
    if (mTemporary)
722
        localSettings_temp.password1 = pw;
723
    else
724
        localSettings.password1 = pw;
725
 
726
    mTemporary = false;
727
}
728
 
729
void TConfig::savePassword2(const std::string& pw)
730
{
731
    DECL_TRACER("TConfig::savePassword2(const std::string& pw)");
732
 
733
    if (mTemporary)
734
        localSettings_temp.password2 = pw;
735
    else
736
        localSettings.password2 = pw;
737
 
738
    mTemporary = false;
739
}
740
 
741
void TConfig::savePassword3(const std::string& pw)
742
{
743
    DECL_TRACER("TConfig::savePassword3(const std::string& pw)");
744
 
745
    if (mTemporary)
746
        localSettings_temp.password3 = pw;
747
    else
748
        localSettings.password3 = pw;
749
 
750
    mTemporary = false;
751
}
752
 
753
void TConfig::savePassword4(const std::string& pw)
754
{
755
    DECL_TRACER("TConfig::savePassword4(const std::string& pw)");
756
 
757
    if (mTemporary)
758
        localSettings_temp.password4 = pw;
759
    else
760
        localSettings.password4 = pw;
761
 
762
    mTemporary = false;
763
}
764
 
765
void TConfig::setUserPassword(const string& user, const string& pw)
766
{
767
    DECL_TRACER("TConfig::setUserPassword(const string& user, const string& pw)");
768
 
769
    userPasswords.insert(pair<string, string>(user, pw));
770
    writeUserPasswords();
771
}
772
 
773
string TConfig::getUserPassword(const string& user)
774
{
775
    map<string, string>::iterator pw = userPasswords.find(user);
776
 
777
    if (pw != userPasswords.end())
778
        return pw->second;
779
 
780
    return string();
781
}
782
 
783
void TConfig::clearUserPassword(const string& user)
784
{
785
    DECL_TRACER("TConfig::clearUserPassword(const string& user)");
786
 
787
    map<string, string>::iterator pw = userPasswords.find(user);
788
 
789
    if (pw != userPasswords.end())
790
    {
791
        userPasswords.erase(pw);
792
        writeUserPasswords();
793
    }
794
}
795
 
796
void TConfig::clearUserPasswords()
797
{
798
    DECL_TRACER("TConfig::clearUserPasswords()");
799
 
800
    if (!userPasswords.empty())
801
    {
802
        userPasswords.clear();
803
        fs::remove(localSettings.path + "/" + fileUserPasswords);
804
    }
805
}
806
 
807
void TConfig::readUserPasswords()
808
{
809
    DECL_TRACER("TConfig::readUserPasswords()");
810
 
811
    string fname = localSettings.path + "/" + fileUserPasswords;
812
 
813
    if (!fs::exists(fname))
484 andreas 814
    {
815
        MSG_DEBUG("Password file \"" << fname << "\" not found!");
446 andreas 816
        return;
484 andreas 817
    }
446 andreas 818
 
819
    ifstream f;
820
 
821
    try
822
    {
823
        f.open(fname);
824
 
825
        for (string line; getline(f, line);)
826
        {
827
            size_t pos = line.find_first_of("|");
828
 
829
            if (pos == string::npos)
830
                continue;
831
 
832
            string user = line.substr(0, pos);
833
            string pass = line.substr(pos + 1);
834
            userPasswords.insert(pair<string, string>(user, pass));
835
        }
836
 
837
        f.close();
838
    }
839
    catch (std::exception& e)
840
    {
841
        MSG_ERROR("Error opening file " << fname << ": " << e.what());
842
 
843
        if (f.is_open())
844
            f.close();
845
    }
846
}
847
 
848
void TConfig::writeUserPasswords()
849
{
850
    DECL_TRACER("TConfig::writeUserPasswords()");
851
 
852
    if (userPasswords.empty())
853
        return;
854
 
855
    string fname = localSettings.path + "/" + fileUserPasswords;
856
    ofstream f;
857
 
858
    try
859
    {
860
        map<string, string>::iterator iter;
861
 
862
        f.open(fname);
863
 
864
        for (iter = userPasswords.begin(); iter != userPasswords.end(); ++iter)
865
        {
866
            string line = iter->first + "|" + iter->second + "\n";
867
            f.write(line.c_str(), line.length());
868
        }
869
 
870
        f.close();
871
    }
872
    catch(std::exception& e)
873
    {
874
        MSG_ERROR("Error reading file " << fname << ": " << e.what());
875
 
876
        if (f.is_open())
877
            f.close();
878
    }
879
}
880
 
881
void TConfig::saveSystemSoundFile(const std::string& snd)
882
{
883
    DECL_TRACER("TConfig::saveSystemSoundFile(const std::string& snd)");
884
 
885
    if (mTemporary)
886
        localSettings_temp.systemSound = snd;
887
    else
888
        localSettings.systemSound = snd;
889
 
890
    mTemporary = false;
891
}
892
 
893
void TConfig::saveSystemSoundState(bool state)
894
{
895
    DECL_TRACER("TConfig::saveSystemSoundState(bool state)");
896
 
897
    if (mTemporary)
898
        localSettings_temp.systemSoundState = state;
899
    else
900
        localSettings.systemSoundState = localSettings_temp.systemSoundState = state;
901
 
902
    mTemporary = false;
903
}
904
 
905
void TConfig::saveSingleBeepFile(const std::string& snd)
906
{
907
    DECL_TRACER("TConfig::saveSingleBeepFile(const std::string& snd)");
908
 
909
    if (mTemporary)
910
        localSettings_temp.systemSingleBeep = snd;
911
    else
912
        localSettings.systemSingleBeep = snd;
913
 
914
    mTemporary = false;
915
}
916
 
917
void TConfig::saveDoubleBeepFile(const std::string& snd)
918
{
919
    DECL_TRACER("TConfig::saveDoubleBeepFile(const std::string& snd)");
920
 
921
    if (mTemporary)
922
        localSettings_temp.systemDoubleBeep = snd;
923
    else
924
        localSettings.systemDoubleBeep = snd;
925
 
926
    mTemporary = false;
927
}
928
 
929
void TConfig::saveSystemVolume(int volume)
930
{
931
    DECL_TRACER("TConfig::saveSystemVolume(int volume)");
932
 
933
    if (volume < 0 || volume > 100)
934
        return;
935
 
936
    if (mTemporary)
937
        localSettings_temp.systemVolume = volume;
938
    else
939
        localSettings.systemVolume = volume;
940
 
941
    mTemporary = false;
942
}
943
 
944
void TConfig::saveSystemGain(int gain)
945
{
946
    DECL_TRACER("TConfig::saveSystemGain(int gain)");
947
 
948
    if (gain < 0 || gain > 100)
949
        return;
950
 
951
    if (mTemporary)
952
        localSettings_temp.systemGain = gain;
953
    else
954
        localSettings.systemGain = gain;
955
 
956
    mTemporary = false;
957
}
958
 
959
void TConfig::saveFtpUser(const string& user)
960
{
961
    DECL_TRACER("TConfig::saveFtpUser(const string& user)");
962
 
963
    if (mTemporary)
964
        localSettings_temp.ftpUser = user;
965
    else
966
        localSettings.ftpUser = user;
967
 
968
    mTemporary = false;
969
}
970
 
971
void TConfig::saveFtpPassword(const string& pw)
972
{
973
    DECL_TRACER("TConfig::saveFtpPassword(const string& pw)");
974
 
975
    if (mTemporary)
976
        localSettings_temp.ftpPassword = pw;
977
    else
978
        localSettings.ftpPassword = pw;
979
 
980
    mTemporary = false;
981
}
982
 
983
void TConfig::saveFtpSurface(const string& fname)
984
{
985
    DECL_TRACER("TConfig::saveFtpSurface(const string& fname)");
986
 
987
    if (mTemporary)
988
        localSettings_temp.ftpSurface = fname;
989
    else
990
        localSettings.ftpSurface = fname;
991
 
992
    mTemporary = false;
993
}
994
 
995
void TConfig::saveFtpPassive(bool mode)
996
{
997
    DECL_TRACER("TConfig::saveFtpPassive(bool mode)");
998
 
999
    if (mTemporary)
1000
        localSettings_temp.ftpPassive = mode;
1001
    else
1002
        localSettings.ftpPassive = mode;
1003
 
1004
    mTemporary = false;
1005
}
1006
 
1007
void TConfig::saveFtpDownloadTime(time_t t)
1008
{
1009
    DECL_TRACER("TConfig::saveFtpDownloadTime(time_t t)");
1010
 
1011
    if (mTemporary)
1012
        localSettings_temp.ftpLastDownload = t;
1013
    else
1014
        localSettings.ftpLastDownload = t;
1015
 
1016
    mTemporary = false;
1017
}
1018
 
1019
std::string& TConfig::getSIPproxy()
1020
{
1021
    DECL_TRACER("TConfig::getSIPproxy()");
1022
 
1023
    return mTemporary ? localSettings_temp.sip_proxy : localSettings.sip_proxy;
1024
}
1025
 
1026
void TConfig::setSIPproxy(const std::string& address)
1027
{
1028
    DECL_TRACER("TConfig::setSIPproxy(const std::string& address)");
1029
 
1030
    if (mTemporary)
1031
        localSettings_temp.sip_proxy = address;
1032
    else
1033
        localSettings.sip_proxy = address;
1034
 
1035
    mTemporary = false;
1036
}
1037
 
1038
int TConfig::getSIPport()
1039
{
1040
    DECL_TRACER("TConfig::getSIPport()");
1041
 
1042
    return mTemporary ? localSettings_temp.sip_port : localSettings.sip_port;
1043
}
1044
 
1045
void TConfig::setSIPport(int port)
1046
{
1047
    DECL_TRACER("TConfig::setSIPport(int port)");
1048
 
1049
    if (mTemporary)
1050
        localSettings_temp.sip_port = port;
1051
    else
1052
        localSettings.sip_port = port;
1053
 
1054
    mTemporary = false;
1055
}
1056
 
1057
int TConfig::getSIPportTLS()
1058
{
1059
    DECL_TRACER("TConfig::getSIPportTLS()");
1060
 
1061
    return mTemporary ? localSettings_temp.sip_portTLS : localSettings.sip_portTLS;
1062
}
1063
 
1064
void TConfig::setSIPportTLS(int port)
1065
{
1066
    DECL_TRACER("TConfig::setSIPportTLS(int port)");
1067
 
1068
    if (mTemporary)
1069
        localSettings_temp.sip_portTLS = port;
1070
    else
1071
        localSettings.sip_portTLS = port;
1072
 
1073
    mTemporary = false;
1074
}
1075
 
1076
std::string& TConfig::getSIPstun()
1077
{
1078
    DECL_TRACER("TConfig::getSIPstun()");
1079
 
1080
    return mTemporary ? localSettings_temp.sip_stun : localSettings.sip_stun;
1081
}
1082
 
1083
void TConfig::setSIPstun(const std::string& address)
1084
{
1085
    DECL_TRACER("TConfig::setSIPstun(const std::string& address)");
1086
 
1087
    if (mTemporary)
1088
        localSettings_temp.sip_stun = address;
1089
    else
1090
        localSettings.sip_stun = address;
1091
 
1092
    mTemporary = false;
1093
}
1094
 
1095
std::string& TConfig::getSIPdomain()
1096
{
1097
    DECL_TRACER("TConfig::getSIPdomain()");
1098
 
1099
    return mTemporary ? localSettings_temp.sip_domain : localSettings.sip_domain;
1100
}
1101
 
1102
void TConfig::setSIPdomain(const std::string& domain)
1103
{
1104
    DECL_TRACER("TConfig::setSIPdomain(const std::string& domain)");
1105
 
1106
    if (mTemporary)
1107
        localSettings_temp.sip_domain = domain;
1108
    else
1109
        localSettings.sip_domain = domain;
1110
 
1111
    mTemporary = false;
1112
}
1113
 
1114
std::string& TConfig::getSIPuser()
1115
{
1116
    DECL_TRACER("TConfig::getSIPuser()");
1117
 
1118
    return mTemporary ? localSettings_temp.sip_user : localSettings.sip_user;
1119
}
1120
 
1121
void TConfig::setSIPuser(const std::string& user)
1122
{
1123
    DECL_TRACER("TConfig::setSIPuser(const std::string& user)");
1124
 
1125
    if (mTemporary)
1126
        localSettings_temp.sip_user = user;
1127
    else
1128
        localSettings.sip_user = user;
1129
 
1130
    mTemporary = false;
1131
}
1132
 
1133
std::string& TConfig::getSIPpassword()
1134
{
1135
    DECL_TRACER("TConfig::getSIPpassword()");
1136
 
1137
    return mTemporary ? localSettings_temp.sip_password : localSettings.sip_password;
1138
}
1139
 
1140
void TConfig::setSIPpassword(const std::string& pw)
1141
{
1142
    DECL_TRACER("TConfig::setSIPpassword(const std::string& pw)");
1143
 
1144
    if (mTemporary)
1145
        localSettings_temp.sip_password = pw;
1146
    else
1147
        localSettings.sip_password = pw;
1148
 
1149
    mTemporary = false;
1150
}
1151
 
1152
bool TConfig::getSIPstatus()
1153
{
1154
    DECL_TRACER("TConfig::getSIPstatus()");
1155
 
1156
    return mTemporary ? localSettings_temp.sip_enabled : localSettings.sip_enabled;
1157
}
1158
 
1159
bool TConfig::getSIPnetworkIPv4()
1160
{
1161
    DECL_TRACER("TConfig::getSIPnetworkIPv4()");
1162
 
1163
    return mTemporary ? localSettings_temp.sip_ipv4 : localSettings.sip_ipv4;
1164
}
1165
 
1166
void TConfig::setSIPnetworkIPv4(bool state)
1167
{
1168
    DECL_TRACER("TConfig::setSIPnetworkIPv4(bool state)");
1169
 
1170
    if (mTemporary)
1171
        localSettings_temp.sip_ipv4 = state;
1172
    else
1173
        localSettings.sip_ipv4 = state;
1174
 
1175
    mTemporary = false;
1176
}
1177
 
1178
bool TConfig::getSIPnetworkIPv6()
1179
{
1180
    DECL_TRACER("TConfig::getSIPnetworkIPv6()");
1181
 
1182
    return mTemporary ? localSettings_temp.sip_ipv6 : localSettings.sip_ipv6;
1183
}
1184
 
1185
void TConfig::setSIPnetworkIPv6(bool state)
1186
{
1187
    DECL_TRACER("TConfig::setSIPnetworkIPv6(bool state)");
1188
 
1189
    if (mTemporary)
1190
        localSettings_temp.sip_ipv6 = state;
1191
    else
1192
        localSettings.sip_ipv6 = state;
1193
 
1194
    mTemporary = false;
1195
}
1196
 
1197
void TConfig::setSIPiphone(bool state)
1198
{
1199
    DECL_TRACER("TConfig::setSIPiphone(bool state)");
1200
 
1201
    if (mTemporary)
1202
        localSettings_temp.sip_iphone = state;
1203
    else
1204
        localSettings.sip_iphone = state;
1205
 
1206
    mTemporary = false;
1207
}
1208
 
1209
bool TConfig::getSIPiphone()
1210
{
1211
    DECL_TRACER("TConfig::getSIPiphone()");
1212
 
1213
    return mTemporary ? localSettings_temp.sip_iphone : localSettings.sip_iphone;
1214
}
1215
 
1216
TConfig::SIP_FIREWALL_t TConfig::getSIPfirewall()
1217
{
1218
    DECL_TRACER("TConfig::getSIPfirewall()");
1219
 
1220
    return mTemporary ? localSettings_temp.sip_firewall : localSettings.sip_firewall;
1221
}
1222
 
1223
string TConfig::getSIPfirewallStr()
1224
{
1225
    DECL_TRACER("TConfig::getSIPfirewallStr()");
1226
 
1227
    return sipFirewallToString(mTemporary ? localSettings_temp.sip_firewall : localSettings.sip_firewall);
1228
}
1229
 
1230
void TConfig::setSIPfirewall(TConfig::SIP_FIREWALL_t fw)
1231
{
1232
    DECL_TRACER("TConfig::setSIPfirewall(TConfig::SIP_FIREWALL_t fw)")
1233
 
1234
    if (mTemporary)
1235
        localSettings_temp.sip_firewall = fw;
1236
    else
1237
        localSettings.sip_firewall = fw;
1238
 
1239
    mTemporary = false;
1240
}
1241
 
1242
void TConfig::setSIPstatus(bool state)
1243
{
1244
    DECL_TRACER("TConfig::setSIPstatus(bool state)");
1245
 
1246
    if (mTemporary)
1247
        localSettings_temp.sip_enabled = state;
1248
    else
1249
        localSettings.sip_enabled = state;
1250
 
1251
    mTemporary = false;
1252
}
1253
 
480 andreas 1254
string TConfig::getApp(const string& id)
1255
{
1256
    DECL_TRACER("TConfig::getApp(const string& id)");
1257
 
482 andreas 1258
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
480 andreas 1259
    if (localSettings.apps.empty())
1260
        return string();
1261
 
1262
    vector<_APPS_t>::iterator iter;
1263
 
1264
    for (iter = localSettings.apps.begin(); iter != localSettings.apps.end(); ++iter)
1265
    {
1266
        if (iter->appID == id)
1267
            return iter->path;
1268
    }
482 andreas 1269
#endif
480 andreas 1270
    return string();
1271
}
1272
 
446 andreas 1273
bool TConfig::saveSettings()
1274
{
1275
    DECL_TRACER("TConfig::saveSettings()");
1276
 
1277
    TLock<std::mutex> guard(config_mutex);
1278
 
1279
    try
1280
    {
1281
        string fname = localSettings.path + "/" + localSettings.name;
1282
 
1283
        if (mTemporary)
1284
        {
1285
            localSettings = localSettings_temp;
1286
            MSG_INFO("Temporary settings were copied over.");
1287
        }
1288
 
1289
        MSG_DEBUG("Saving to file " << fname);
1290
        ofstream file(fname);
1291
        string lines = "LogFile=" + localSettings.logFile + "\n";
1292
        lines += "LogLevel=" + localSettings.logLevel + "\n";
1293
        lines += "ProjectPath=" + localSettings.project + "\n";
1294
        lines += string("NoBanner=") + (localSettings.noBanner ? "true" : "false") + "\n";
1295
        lines += string("ToolbarSuppress=") + (localSettings.tbsuppress ? "true" : "false") + "\n";
1296
        lines += string("ToolbarForce=") + (localSettings.tbforce ? "true" : "false") + "\n";
1297
        lines += string("LongFormat=") + (localSettings.longformat ? "true" : "false") + "\n";
1298
        lines += "Address=" + localSettings.server + "\n";
1299
        lines += "Port=" + std::to_string(localSettings.port) + "\n";
1300
        lines += "Channel=" + std::to_string(localSettings.ID) + "\n";
1301
        lines += "System=" + std::to_string(localSettings.system) + "\n";
1302
        lines += "PanelType=" + localSettings.ptype + "\n";
1303
        lines += "Firmware=" + localSettings.version + "\n";
1304
        lines += string("CertCheck=") + (localSettings.certCheck ? "true" : "false") + "\n";
1305
        lines += string("Scale=") + (localSettings.scale ? "true" : "false") + "\n";
1306
        lines += string("Profiling=") + (localSettings.profiling ? "true" : "false") + "\n";
1307
        lines += "MaxButtonCache=" + std::to_string(localSettings.max_cache) + "\n";
1308
        lines += string("Password1=") + localSettings.password1 + "\n";
1309
        lines += string("Password2=") + localSettings.password2 + "\n";
1310
        lines += string("Password3=") + localSettings.password3 + "\n";
1311
        lines += string("Password4=") + localSettings.password4 + "\n";
1312
        lines += string("SystemSoundFile=") + localSettings.systemSound + "\n";
1313
        lines += string("SystemSoundState=") + (localSettings.systemSoundState ? "ON" : "OFF") + "\n";
1314
        lines += string("SystemSingleBeep=") + localSettings.systemSingleBeep + "\n";
1315
        lines += string("SystemDoubleBeep=") + localSettings.systemDoubleBeep + "\n";
1316
        lines += "SystemVolume=" + std::to_string(localSettings.systemVolume) + "\n";
1317
        lines += "SystemGain=" + std::to_string(localSettings.systemGain) + "\n";
1318
        lines += string("SystemRotationFix=") + (localSettings.systemRotationFix ? "ON" : "OFF") + "\n";
1319
        lines += string("UUID=") + localSettings.uuid + "\n";
1320
        // FTP credentials
1321
        lines += string("FTPuser=") + localSettings.ftpUser + "\n";
1322
        lines += string("FTPpassword=") + localSettings.ftpPassword + "\n";
1323
        lines += string("FTPsurface=") + localSettings.ftpSurface + "\n";
1324
        lines += string("FTPpassive=") + (localSettings.ftpPassive ? "true" : "false") + "\n";
1325
        lines += string("FTPdownloadTime=") + std::to_string(localSettings.ftpLastDownload) + "\n";
1326
        // SIP settings
1327
        lines += string("SIP_DOMAIN=") + localSettings.sip_domain + "\n";
1328
        lines += string("SIP_PROXY=") + localSettings.sip_proxy + "\n";
1329
        lines += string("SIP_PORT=") + std::to_string(localSettings.sip_port) + "\n";
1330
        lines += string("SIP_PORTTLS=") + std::to_string(localSettings.sip_portTLS) + "\n";
1331
        lines += string("SIP_STUN=") + localSettings.sip_stun + "\n";
1332
        lines += string("SIP_USER=") + localSettings.sip_user + "\n";
1333
        lines += string("SIP_PASSWORD=") + localSettings.sip_password + "\n";
1334
        lines += string("SIP_IPV4=") + (localSettings.sip_ipv4 ? "true" : "false") + "\n";
1335
        lines += string("SIP_IPV6=") + (localSettings.sip_ipv6 ? "true" : "false") + "\n";
1336
        lines += string("SIP_IPHONE=") + (localSettings.sip_iphone ? "true" : "false") + "\n";
1337
        lines += "SIP_FIREWALL=" + sipFirewallToString(localSettings.sip_firewall) + "\n";
1338
        lines += string("SIP_ENABLED=") + (localSettings.sip_enabled ? "true" : "false") + "\n";
482 andreas 1339
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
480 andreas 1340
        if (!localSettings.apps.empty())
1341
        {
1342
            vector<_APPS_t>::iterator iter;
1343
 
1344
            for (iter = localSettings.apps.begin(); iter != localSettings.apps.end(); ++iter)
1345
                lines += "APP=" + iter->appID + ";" + iter->path + "\n";
1346
        }
482 andreas 1347
#endif
446 andreas 1348
        file.write(lines.c_str(), lines.size());
1349
        file.close();
1350
        MSG_INFO("Actual log level: " << localSettings.logLevel);
1351
 
1352
        if (mTemporary)
1353
        {
1354
            TError::Current()->setLogLevel(localSettings.logLevel);
1355
            TError::Current()->setLogFile(localSettings.logFile);
1356
        }
1357
 
1358
        mTemporary = false;
1359
    }
1360
    catch (std::exception& e)
1361
    {
1362
        MSG_ERROR("Couldn't write configs: " << e.what());
1363
        return false;
1364
    }
1365
 
1366
    return true;
1367
}
1368
 
1369
/**
1370
 * @brief TConfig::isLongFormat defines the format in the logfile.
1371
 *
1372
 * If this returns `true` the format in the logfile is a long format. This
1373
 * means, that in front of each message is an additional timestamp.
1374
 *
1375
 * @return `true` = long format, `false` = short format (default).
1376
 */
1377
bool TConfig::isLongFormat()
1378
{
1379
    return mTemporary ? localSettings_temp.longformat : localSettings.longformat;
1380
}
1381
 
1382
/**
1383
 * @brief TConfig::showBanner defines whether the banner should be showed or not.
1384
 *
1385
 * If this method returns `false` the banner on startup is not displayed.
1386
 *
1387
 * @return `true` = display the banner (default), `false` = show no banner.
1388
 */
1389
bool TConfig::showBanner()
1390
{
1391
    DECL_TRACER("TConfig::showBanner()");
1392
 
1393
    return mTemporary ? (!localSettings_temp.noBanner) : (!localSettings.noBanner);
1394
}
1395
 
1396
/**
1397
 * @brief TConfig::getScale returns the scale setting
1398
 *
1399
 * If this is set to TRUE, all images are scaled to fit the screen.
1400
 *
1401
 * @return scale state
1402
 */
1403
bool TConfig::getScale()
1404
{
1405
    DECL_TRACER("TConfig::getScale()");
1406
 
1407
    return mTemporary ? localSettings_temp.scale : localSettings.scale;
1408
}
1409
 
1410
bool TConfig::getToolbarForce()
1411
{
1412
    DECL_TRACER("TConfig::getToolbarForce()");
1413
 
1414
    return mTemporary ? localSettings_temp.tbforce : localSettings.tbforce;
1415
}
1416
 
1417
bool TConfig::getToolbarSuppress()
1418
{
1419
    DECL_TRACER("TConfig::getToolbarSuppress()");
1420
 
1421
    return mTemporary ? localSettings_temp.tbsuppress : localSettings.tbsuppress;
1422
}
1423
 
1424
bool TConfig::getProfiling()
1425
{
1426
    return mTemporary ? localSettings_temp.profiling : localSettings.profiling;
1427
}
1428
 
1429
size_t TConfig::getButttonCache()
1430
{
1431
    if (mTemporary && localSettings_temp.max_cache > 0)
1432
        return localSettings_temp.max_cache;
1433
 
1434
    if (!mTemporary && localSettings.max_cache > 0)
1435
        return localSettings.max_cache * 1000 * 1000;
1436
 
1437
    return 0;
1438
}
1439
 
1440
string & TConfig::getPassword1()
1441
{
1442
    DECL_TRACER("TConfig::getPassword1()");
1443
 
1444
    return mTemporary ? localSettings_temp.password1 : localSettings.password1;
1445
}
1446
 
1447
string & TConfig::getPassword2()
1448
{
1449
    DECL_TRACER("TConfig::getPassword2()");
1450
 
1451
    return mTemporary ? localSettings_temp.password2 : localSettings.password2;
1452
}
1453
 
1454
string & TConfig::getPassword3()
1455
{
1456
    DECL_TRACER("TConfig::getPassword3()");
1457
 
1458
    return mTemporary ? localSettings_temp.password3 : localSettings.password3;
1459
}
1460
 
1461
string & TConfig::getPassword4()
1462
{
1463
    DECL_TRACER("TConfig::getPassword4()");
1464
 
1465
    return mTemporary ? localSettings_temp.password4 : localSettings.password4;
1466
}
1467
 
1468
string & TConfig::getSystemSound()
1469
{
1470
    DECL_TRACER("TConfig::getSystemSound()");
1471
 
1472
    return mTemporary ? localSettings_temp.systemSound : localSettings.systemSound;
1473
}
1474
 
1475
bool TConfig::getSystemSoundState()
1476
{
1477
    DECL_TRACER("TConfig::getSystemSoundState()");
1478
 
1479
    return mTemporary ? localSettings_temp.systemSoundState : localSettings.systemSoundState;
1480
}
1481
 
1482
int TConfig::getSystemVolume()
1483
{
1484
    DECL_TRACER("TConfig::getSystemVolume()");
1485
 
1486
    return mTemporary ? localSettings_temp.systemVolume : localSettings.systemVolume;
1487
}
1488
 
1489
int TConfig::getSystemGain()
1490
{
1491
    DECL_TRACER("TConfig::getSystemGain()");
1492
 
1493
    return mTemporary ? localSettings_temp.systemGain : localSettings.systemGain;
1494
}
1495
 
1496
bool TConfig::getRotationFixed()
1497
{
1498
    DECL_TRACER("TConfig::getRotationFixed()");
1499
 
1500
    return mTemporary ? localSettings_temp.systemRotationFix : localSettings.systemRotationFix;
1501
}
1502
 
1503
void TConfig::setRotationFixed(bool fix)
1504
{
1505
    DECL_TRACER("TConfig::setRotationFixed(bool fix)");
1506
 
1507
    if (mTemporary)
1508
        localSettings_temp.systemRotationFix = fix;
1509
    else
1510
        localSettings.systemRotationFix = fix;
1511
 
1512
    mTemporary = false;
1513
}
1514
 
1515
void TConfig::setSystemChannel(int ch)
1516
{
1517
    DECL_TRACER("TConfig::setSystemChannel(int ch)");
1518
 
1519
    if (ch >= 10000 && ch < 30000)
1520
        mChannel = ch;
1521
}
1522
 
1523
string& TConfig::getSingleBeepSound()
1524
{
1525
    DECL_TRACER("TConfig::getSingleBeepSound()");
1526
 
1527
    return mTemporary ? localSettings_temp.systemSingleBeep : localSettings.systemSingleBeep;
1528
}
1529
 
1530
string& TConfig::getDoubleBeepSound()
1531
{
1532
    DECL_TRACER("TConfig::getDoubleBeepSound()");
1533
 
1534
    return mTemporary ? localSettings_temp.systemDoubleBeep : localSettings.systemDoubleBeep;
1535
}
1536
 
1537
string& TConfig::getUUID()
1538
{
1539
    DECL_TRACER("TConfig::getUUID()");
1540
 
1541
    return mTemporary ? localSettings_temp.uuid : localSettings.uuid;
1542
}
1543
 
1544
string& TConfig::getFtpUser()
1545
{
1546
    DECL_TRACER("TConfig::getFtpUser()");
1547
 
1548
    return mTemporary ? localSettings_temp.ftpUser : localSettings.ftpUser;
1549
}
1550
 
1551
string& TConfig::getFtpPassword()
1552
{
1553
    DECL_TRACER("TConfig::getFtpPassword()");
1554
 
1555
    return mTemporary ? localSettings_temp.ftpPassword : localSettings.ftpPassword;
1556
}
1557
 
1558
string& TConfig::getFtpSurface()
1559
{
1560
    DECL_TRACER("TConfig::getFtpSurface()");
1561
 
1562
    return mTemporary ? localSettings_temp.ftpSurface : localSettings.ftpSurface;
1563
}
1564
 
1565
bool TConfig::getFtpPassive()
1566
{
1567
    DECL_TRACER("TConfig::getFtpPassive()");
1568
 
1569
    return mTemporary ? localSettings_temp.ftpPassive : localSettings.ftpPassive;
1570
}
1571
 
1572
time_t TConfig::getFtpDownloadTime()
1573
{
1574
    DECL_TRACER("TConfig::getFtpDownloadTime()");
1575
 
1576
    return mTemporary ? localSettings_temp.ftpLastDownload : localSettings.ftpLastDownload;
1577
}
1578
 
1579
/**
1580
 * @brief TConfig::certCheck check the certificate if the connection is encrypted.
1581
 *
1582
 * Currently not implemented!
1583
 *
1584
 * @return `true` = check the certificate, `false` = accept any certificate (default).
1585
 */
1586
bool TConfig::certCheck()
1587
{
1588
    return mTemporary ? localSettings_temp.certCheck : localSettings.certCheck;
1589
}
1590
 
1591
/**
1592
 * @brief TConfig::logLevelStrToBits
1593
 * Converts a string containing one or more loglevels into a bit field.
1594
 * @param level A string containing the log levels
1595
 * @return A bit field representing the log levels.
1596
 */
1597
uint TConfig::logLevelStrToBits(const string& level)
1598
{
1599
    uint l = 0;
1600
 
1601
    if (level.find("INFO") != string::npos)
1602
        l |= HLOG_INFO;
1603
 
1604
    if (level.find("WARNING") != string::npos)
1605
        l |= HLOG_WARNING;
1606
 
1607
    if (level.find("ERROR") != string::npos)
1608
        l |= HLOG_ERROR;
1609
 
1610
    if (level.find("TRACE") != string::npos)
1611
        l |= HLOG_TRACE;
1612
 
1613
    if (level.find("DEBUG") != string::npos)
1614
        l |= HLOG_DEBUG;
1615
 
1616
    if (level.find("PROTOCOL") != string::npos)
1617
        l |= HLOG_PROTOCOL;
1618
 
1619
    if (level.find("ALL") != string::npos)
1620
        l = HLOG_ALL;
1621
 
1622
    return l;
1623
}
1624
 
1625
string TConfig::logLevelBitsToString(uint level)
1626
{
1627
    string l;
1628
 
1629
    if (level == 0)
1630
    {
1631
        l = SLOG_NONE;
1632
        return l;
1633
    }
1634
 
1635
    if (level & HLOG_INFO)
1636
    {
1637
        if (l.length() > 0)
1638
            l.append("|");
1639
 
1640
        l.append(SLOG_INFO);
1641
    }
1642
 
1643
    if (level & HLOG_WARNING)
1644
    {
1645
        if (l.length() > 0)
1646
            l.append("|");
1647
 
1648
        l.append(SLOG_WARNING);
1649
    }
1650
 
1651
    if (level & HLOG_ERROR)
1652
    {
1653
        if (l.length() > 0)
1654
            l.append("|");
1655
 
1656
        l.append(SLOG_ERROR);
1657
    }
1658
 
1659
    if (level & HLOG_TRACE)
1660
    {
1661
        if (l.length() > 0)
1662
            l.append("|");
1663
 
1664
        l.append(SLOG_TRACE);
1665
    }
1666
 
1667
    if (level & HLOG_DEBUG)
1668
    {
1669
        if (l.length() > 0)
1670
            l.append("|");
1671
 
1672
        l.append(SLOG_DEBUG);
1673
    }
1674
 
1675
    return l;
1676
}
1677
 
1678
string TConfig::sipFirewallToString(TConfig::SIP_FIREWALL_t fw)
1679
{
1680
    switch(fw)
1681
    {
1682
        case SIP_NO_FIREWALL:   return "SIP_NO_FIREWALL";
1683
        case SIP_NAT_ADDRESS:   return "SIP_NAT_ADDRESS";
1684
        case SIP_STUN:          return "SIP_STUN";
1685
        case SIP_ICE:           return "SIP_ICE";
1686
        case SIP_UPNP:          return "SIP_UPNP";
1687
    }
1688
 
1689
    return string();
1690
}
1691
 
1692
TConfig::SIP_FIREWALL_t TConfig::sipFirewallStrToEnum(const std::string& str)
1693
{
1694
    if (strCaseCompare(str, "SIP_NO_FIREWALL") == 0)
1695
        return SIP_NO_FIREWALL;
1696
    else if (strCaseCompare(str, "SIP_NAT_ADDRESS") == 0)
1697
        return SIP_NAT_ADDRESS;
1698
    else if (strCaseCompare(str, "SIP_STUN") == 0)
1699
        return SIP_STUN;
1700
    else if (strCaseCompare(str, "SIP_ICE") == 0)
1701
        return SIP_ICE;
1702
    else if (strCaseCompare(str, "SIP_UPNP") == 0)
1703
        return SIP_UPNP;
1704
 
1705
    return SIP_NO_FIREWALL;
1706
}
1707
 
1708
string TConfig::makeConfigDefault(const std::string& log, const std::string& project)
1709
{
1710
    string content = "LogFile=" + log + "\n";
1711
#ifndef NDEBUG
1712
    content += "LogLevel=ALL\n";
1713
#else
1714
    content += "LogLevel=NONE\n";
1715
#endif
1716
    content += "ProjectPath=" + project + "\n";
1717
    content += "LongFormat=false\n";
1718
    content += "Address=0.0.0.0\n";
1719
    content += "Port=1319\n";
1720
    content += "Channel=10001\n";
1721
    content += "PanelType=Android\n";
1722
    content += string("Firmware=") + VERSION_STRING() + "\n";
1723
    content += "Scale=true\n";
1724
    content += "ToolbarForce=true\n";
1725
    content += "Profiling=false\n";
1726
    content += "Password1=1988\n";
1727
    content += "Password2=1988\n";
1728
    content += "Password3=1988\n";
1729
    content += "Password4=1988\n";
1730
    content += "SystemSoundFile=singleBeep.wav\n";
1731
    content += "SystemSoundState=ON\n";
1732
    content += "SystemSingleBeep=singleBeep01.wav\n";
1733
    content += "SystemDoubleBeep=doubleBeep01.wav\n";
1734
    content += "SystemRotationFix=" + string(localSettings.systemRotationFix ? "TRUE" : "FALSE") + "\n";
1735
    content += "UUID=" + localSettings.uuid + "\n";
1736
    content += "FTPuser=administrator\n";
1737
    content += "FTPpassword=password\n";
1738
    content += "FTPsurface=tpanel.TP4\n";
1739
    content += "FTPpassive=true\n";
1740
    content += "FTPdownloadTime=0\n";
1741
    content += "SIP_PROXY=" + localSettings.sip_proxy + "\n";
1742
    content += "SIP_PORT=" + std::to_string(localSettings.sip_port) + "\n";
1743
    content += "SIP_PORTTLS=" + std::to_string(localSettings.sip_portTLS) + "\n";
1744
    content += "SIP_STUN=" + localSettings.sip_stun + "\n";
1745
    content += "SIP_DOMAIN=" + localSettings.sip_domain + "\n";
1746
    content += "SIP_USER=" + localSettings.sip_user + "\n";
1747
    content += "SIP_PASSWORD=" + localSettings.sip_password + "\n";
1748
    content += "SIP_IPV4=" + string(localSettings.sip_ipv4 ? "TRUE" : "FALSE") + "\n";
1749
    content += "SIP_IPV6=" + string(localSettings.sip_ipv6 ? "TRUE" : "FALSE") + "\n";
1750
    content += "SIP_IPHONE=" + string(localSettings.sip_iphone ? "TRUE" : "FALSE") + "\n";
1751
    content += "SIP_FIREWALL=" + sipFirewallToString(localSettings.sip_firewall) + "\n";
1752
    content += "SIP_ENABLED=" + string(localSettings.sip_ipv6 ? "TRUE" : "FALSE") + "\n";
1753
 
480 andreas 1754
#ifdef __linux__
1755
    content += string("APP=Calculator;/usr/bin/kcalc\n");
1756
    content += string("APP=PDF Viewer;/usr/bin/okular\n");
1757
    content += string("APP=Browser;/usr/bin/firefox\n");
1758
    content += string("APP=Calendar;/usr/bin/kalendar\n");
1759
    content += string("APP=Contacts;/usr/bin/kaddressbook\n");
1760
    content += string("APP=Email;/usr/bin/kmail\n");
1761
    content += string("APP=FileBrowser;/usr/bin/dolphin\n");
1762
    content += string("APP=Gallery;/usr/bin/gwenview\n");
1763
    content += string("APP=Excel Viewer;/usr/bin/libreoffice --calc\n");
1764
    content += string("APP=PowerPoint Viewer;/usr/bin/libreoffice --impress\n");
1765
    content += string("APP=Word Viewer;/usr/bin/libreoffice --writer\n");
1766
#endif
446 andreas 1767
    return content;
1768
}
1769
 
1770
/**
1771
 * @brief TConfig::findConfig search for the location of the configuration file.
1772
 *
1773
 * If there was no configuration file given on the command line, this method
1774
 * searches for a configuration file on a few standard directories. This are:
1775
 *
1776
 *     /etc/tpanel.conf
1777
 *     /etc/tpanel/tpanel.conf
1778
 *     /usr/etc/tpanel.conf
1779
 *     $HOME/.tpanel.conf
1780
 *
1781
 * On macOS the following additional directories are searched:
1782
 *
1783
 *     /opt/local/etc/tpanel.conf
1784
 *     /opt/local/etc/tpanel/tpanel.conf
1785
 *     /opt/local/usr/etc/tpanel.conf
1786
 *
1787
 * @return On success `true`, otherwise `false`.
1788
 */
1789
bool TConfig::findConfig()
1790
{
1791
    TLock<std::mutex> guard(config_mutex);
1792
 
1793
    char *HOME = nullptr;
1794
    string sFileName;
1795
 
1796
    if (!mPath.empty())
1797
    {
1798
        size_t pos = mPath.find_last_of("/");
1799
 
1800
        if (pos != string::npos)
1801
        {
1802
            localSettings.path = mPath.substr(0, pos);
1803
            localSettings.name = mPath.substr(pos+1);
1804
            localSettings_temp.path = localSettings.path;
1805
            localSettings_temp.name = localSettings.name;
1806
            mCFile = mPath;
1807
            return !mCFile.empty();
1808
        }
1809
 
1810
        localSettings.path = ".";
1811
        localSettings.name = mPath;
1812
        localSettings_temp.path = localSettings.path;
1813
        localSettings_temp.name = localSettings.name;
1814
        mCFile = mPath;
1815
        return !mCFile.empty();
1816
    }
1817
 
1818
    localSettings.name = "tpanel.conf";
1819
    localSettings.password1 = "1988";
1820
    localSettings.password2 = "1988";
1821
    localSettings.password3 = "1988";
1822
    localSettings.password4 = "1988";
1823
    localSettings.systemSound = "singleBeep.wav";
1824
    localSettings.systemSoundState = true;
1825
    localSettings.systemSingleBeep = "singleBeep01.wav";
1826
    localSettings.systemDoubleBeep = "doubleBeep01.wav";
1827
    localSettings.ftpUser = "administrator";
1828
    localSettings.ftpPassword = "password";
1829
    localSettings.ftpSurface = "tpanel.tp4";
1830
#ifdef __ANDROID__
1831
    std::stringstream s;
1832
    TValidateFile vf;
1833
    HOME = getenv("HOME");
1834
 
1835
    if (!HOME || !*HOME)
1836
    {
1837
        s << "Error: Environment variable HOME does not exist!";
1838
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", s.str().c_str());
1839
        TError::setErrorMsg(s.str());
1840
        return false;
1841
    }
1842
 
1843
    localSettings.path = HOME;
1844
 
1845
    if (!vf.isValidDir(localSettings.path))
1846
    {
1847
        s << "Error: Path " << localSettings.path << " does not exist!";
1848
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", s.str().c_str());
1849
        TError::setErrorMsg(s.str());
1850
        return false;
1851
    }
1852
 
1853
    sFileName = localSettings.path + "/" + localSettings.name;
1854
 
1855
    if (access(sFileName.c_str(), F_OK) == -1)    // Does the configuration file exist?
1856
    {                                       // No, than create it and also the directory structure
1857
        try
1858
        {
1859
            ofstream cfg(sFileName);
1860
 
1861
            string content = makeConfigDefault(localSettings.path + "/tpanel.log", localSettings.path + "/tpanel");
1862
            cfg.write(content.c_str(), content.size());
1863
            cfg.close();
1864
 
1865
            string path = localSettings.path + "/tpanel";
1866
            TTPInit init(path);
1867
        }
1868
        catch (std::exception& e)
1869
        {
1870
            s << "Error: " << e.what();
1871
            __android_log_print(ANDROID_LOG_ERROR, "tpanel" , "%s", s.str().c_str());
1872
            TError::setErrorMsg(TERRERROR, string("Error: ") + e.what());
1873
            return false;
1874
        }
1875
    }
1876
#else
1877
    if (!(HOME = getenv("HOME")))
1878
        MSG_ERROR("TConfig::findConfig: No environment variable HOME!");
1879
 
1880
    vector<string>::iterator iter;
1881
    bool found = false;
1882
 
1883
    for (iter = mCfgPaths.begin(); iter != mCfgPaths.end(); ++iter)
1884
    {
1885
        string f = *iter + "/tpanel.conf";
1886
 
1887
        if (!access(f.c_str(), R_OK))
1888
        {
1889
            sFileName = f;
1890
            localSettings.path = *iter;
1891
            found = true;
1892
            break;
1893
        }
1894
    }
1895
 
1896
    // The local configuration file has precedence over the global one.
1897
    if (HOME)
1898
    {
1899
        string f = HOME;
1900
#ifndef __ANDROID__
1901
        f += "/.tpanel.conf";
1902
#else
1903
        f += "/tpanel.conf";
1904
#endif
1905
        if (!access(f.data(), R_OK))
1906
        {
1907
            sFileName = f;
1908
            localSettings.path = HOME;
1909
            found = true;
1910
        }
1911
    }
1912
 
1913
    localSettings_temp = localSettings;
1914
 
1915
    if (!found)
1916
    {
1917
        MSG_WARNING("This seems to be the first start because of missing configuration file. Will try to create a default one ...");
1918
 
1919
        if (HOME)
1920
        {
1921
            localSettings.path = HOME;
1922
            sFileName = string(HOME) + "/.tpanel.conf";
1923
 
1924
            try
1925
            {
1926
                ofstream cfg(sFileName);
1927
 
1928
                string content = makeConfigDefault(localSettings.path + "/tpanel.log", localSettings.path + "/tpanel");
1929
                cfg.write(content.c_str(), content.size());
1930
                cfg.close();
1931
 
1932
                localSettings_temp = localSettings;
1933
                string path = localSettings.path + "/tpanel";
1934
                TTPInit init(path);
1935
            }
1936
            catch (std::exception& e)
1937
            {
1938
                cerr << "Error: " << e.what();
1939
                TError::setErrorMsg(TERRERROR, string("Error: ") + e.what());
1940
                return false;
1941
            }
1942
        }
1943
        else
1944
        {
1945
            MSG_ERROR("TConfig::findConfig: Can't find any configuration file!");
1946
            TError::setError();
1947
            sFileName.clear();
1948
            localSettings.name.clear();
1949
            localSettings.path.clear();
1950
            localSettings_temp = localSettings;
1951
        }
1952
    }
1953
#endif
1954
    mCFile = sFileName;
1955
    return !sFileName.empty();
1956
}
1957
 
1958
/**
1959
 * @brief TConfig::readConfig reads a config file.
1960
 *
1961
 * This method reads a config file and stores the known options into the
1962
 * struct localSettings.
1963
 *
1964
 * @return `true` on success.\n
1965
 * Returns `false` on error and sets the internal error.
1966
 */
1967
bool TConfig::readConfig()
1968
{
1969
#if defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_SIMULATOR)
1970
    QASettings settings;
1971
    localSettings.path = QASettings::getLibraryPath().toStdString();
1972
    localSettings.project = localSettings.path + "/tpanel";
1973
    localSettings.version = "1.0";
1974
    localSettings.ptype = "iPhone";
1975
    localSettings.max_cache = 100;
1976
    localSettings.logLevel = SLOG_NONE;
1977
    localSettings.logLevelBits = HLOG_NONE;
1978
    mkdir(localSettings.project.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
1979
    localSettings.name = "tpanel.cfg";
1980
    localSettings.scale = true;
1981
    localSettings.tbforce = false;
1982
    localSettings.tbsuppress = false;
1983
 
1984
    // Settings for NetLinx
1985
    settings.registerDefaultPrefs();
1986
    localSettings.server = settings.getNetlinxIP().toStdString();
1987
    localSettings.port = settings.getNetlinxPort();
1988
    localSettings.ID = settings.getNetlinxChannel();
1989
    localSettings.ptype = settings.getNetlinxPanelType().toStdString();
1990
    localSettings.ftpUser = settings.getFTPUser().toStdString();
1991
    localSettings.ftpPassword = settings.getFTPPassword().toStdString();
1992
    localSettings.ftpSurface = settings.getNetlinxSurface().toStdString();
1993
 
1994
    // Settings for SIP
1995
    localSettings.sip_proxy = settings.getSipProxy().toStdString();
1996
    localSettings.sip_port = settings.getSipNetworkPort();
1997
    localSettings.sip_portTLS = settings.getSipNetworkTlsPort();
1998
    localSettings.sip_stun = settings.getSipStun().toStdString();
1999
    localSettings.sip_domain = settings.getSipDomain().toStdString();
2000
    localSettings.sip_ipv4 = settings.getSipNetworkIpv4();
2001
    localSettings.sip_ipv6 = settings.getSipNetworkIpv6();
2002
    localSettings.sip_user = settings.getSipUser().toStdString();
2003
    localSettings.sip_password = settings.getSipPassword().toStdString();
2004
    localSettings.sip_enabled = settings.getSipEnabled();
2005
    localSettings.sip_iphone = settings.getSipIntegratedPhone();
2006
 
2007
    // Settings for View
2008
    localSettings.scale = settings.getViewScale();
2009
    localSettings.tbforce = settings.getViewToolbarForce();
2010
    localSettings.tbsuppress = !settings.getViewToolbarVisible();
2011
 
2012
    if (localSettings.tbforce)
2013
        localSettings.tbsuppress = false;
2014
 
2015
    localSettings.systemRotationFix = settings.getViewRotation();
2016
 
2017
    // Settings for sound
2018
    localSettings.systemSound = settings.getSoundSystem().toStdString();
2019
    localSettings.systemSingleBeep = settings.getSoundSingleBeep().toStdString();
2020
    localSettings.systemDoubleBeep = settings.getSoundDoubleBeep().toStdString();
2021
    localSettings.systemSoundState = settings.getSoundEnabled();
2022
    localSettings.systemVolume = settings.getSoundVolume();
2023
    localSettings.systemGain = settings.getSoundGain();
2024
 
2025
    // Settings for logging
2026
    unsigned int logLevel = 0;
2027
 
2028
    if (settings.getLoggingInfo())
2029
        logLevel |= HLOG_INFO;
2030
 
2031
    if (settings.getLoggingWarning())
2032
        logLevel |= HLOG_WARNING;
2033
 
2034
    if (settings.getLoggingError())
2035
        logLevel |= HLOG_ERROR;
2036
 
2037
    if (settings.getLoggingDebug())
2038
        logLevel |= HLOG_DEBUG;
2039
 
2040
    if (settings.getLoggingTrace())
2041
        logLevel |= HLOG_TRACE;
2042
 
2043
    if (settings.getLoggingProfile())
2044
        localSettings.profiling = true;
2045
    else
2046
        localSettings.profiling = false;
2047
 
2048
    if (settings.getLoggingLogFormat())
2049
        localSettings.longformat = true;
2050
    else
2051
        localSettings.longformat = false;
2052
 
2053
    localSettings.logLevelBits = logLevel;
2054
    localSettings.logLevel = logLevelBitsToString(logLevel);
2055
    TStreamError::setLogLevel(localSettings.logLevel);
2056
 
2057
    if (settings.getLoggingLogfileEnabled())
2058
    {
2059
        string fname = settings.getLoggingLogfile().toStdString();
2060
 
2061
        if (!fname.empty())
2062
        {
2063
            localSettings.logFile = QASettings::getDocumentPath().toStdString() + "/" + fname;
2064
            TStreamError::setLogFile(localSettings.logFile);
2065
        }
2066
    }
2067
    else
2068
        localSettings.logFile.clear();
2069
 
2070
    if (localSettings.uuid.empty())
2071
    {
2072
        uuid_t uuid;
2073
        char sUUID[256];
2074
 
2075
        uuid_generate_random(uuid);
2076
        uuid_unparse_lower(uuid, sUUID);
2077
        localSettings.uuid.assign(sUUID);
2078
        localSettings_temp = localSettings;
2079
    }
2080
 
2081
    localSettings.password1 = settings.getPassword1().toStdString();
2082
    localSettings.password2 = settings.getPassword2().toStdString();
2083
    localSettings.password3 = settings.getPassword3().toStdString();
2084
    localSettings.password4 = settings.getPassword4().toStdString();
2085
    mInitialized = true;
2086
 
2087
    if (IS_LOG_DEBUG())
2088
    {
2089
        cout << "Selected Parameters:" << endl;
2090
        cout << "    Path to cfg.: " << localSettings.path << endl;
2091
        cout << "    Name of cfg.: " << localSettings.name << endl;
2092
        cout << "    Logfile use:  " << (settings.getLoggingLogfileEnabled() ? "YES": "NO") << endl;
2093
        cout << "    Logfile:      " << localSettings.logFile  << endl;
2094
        cout << "    LogLevel:     " << localSettings.logLevel  << endl;
2095
        cout << "    Long format:  " << (localSettings.longformat ? "YES" : "NO")  << endl;
2096
        cout << "    Project path: " << localSettings.project  << endl;
2097
        cout << "    Controller:   " << localSettings.server  << endl;
2098
        cout << "    Port:         " << localSettings.port  << endl;
2099
        cout << "    Channel:      " << localSettings.ID  << endl;
2100
        cout << "    Panel type:   " << localSettings.ptype  << endl;
2101
        cout << "    Firmware ver. " << localSettings.version  << endl;
2102
        cout << "    Scaling:      " << (localSettings.scale ? "YES" : "NO")  << endl;
2103
        cout << "    Profiling:    " << (localSettings.profiling ? "YES" : "NO")  << endl;
2104
        cout << "    Button cache: " << localSettings.max_cache  << endl;
2105
        cout << "    System Sound: " << localSettings.systemSound  << endl;
2106
        cout << "    Sound state:  " << (localSettings.systemSoundState ? "ACTIVATED" : "DEACTIVATED")  << endl;
2107
        cout << "    Single beep:  " << localSettings.systemSingleBeep  << endl;
2108
        cout << "    Double beep:  " << localSettings.systemDoubleBeep  << endl;
2109
        cout << "    Volume:       " << localSettings.systemVolume  << endl;
2110
        cout << "    Gain:         " << localSettings.systemGain  << endl;
2111
        cout << "    Rotation:     " << (localSettings.systemRotationFix ? "LOCKED" : "UNLOCKED")  << endl;
2112
        cout << "    UUID:         " << localSettings.uuid  << endl;
2113
        cout << "    FTP user:     " << localSettings.ftpUser  << endl;
2114
        cout << "    FTP password: " << localSettings.ftpPassword  << endl;
2115
        cout << "    FTP surface:  " << localSettings.ftpSurface  << endl;
2116
        cout << "    FTP passive:  " << (localSettings.ftpPassive ? "YES" : "NO")  << endl;
2117
        cout << "    FTP dl. time: " << localSettings.ftpLastDownload  << endl;
2118
        cout << "    SIP proxy:    " << localSettings.sip_proxy  << endl;
2119
        cout << "    SIP port:     " << localSettings.sip_port  << endl;
2120
        cout << "    SIP TLS port: " << localSettings.sip_portTLS  << endl;
2121
        cout << "    SIP STUN:     " << localSettings.sip_stun  << endl;
2122
        cout << "    SIP doamain:  " << localSettings.sip_domain  << endl;
2123
        cout << "    SIP user:     " << localSettings.sip_user  << endl;
2124
        cout << "    SIP IPv4:     " << (localSettings.sip_ipv4 ? "YES" : "NO")  << endl;
2125
        cout << "    SIP IPv6:     " << (localSettings.sip_ipv6 ? "YES" : "NO")  << endl;
2126
        cout << "    SIP Int.Phone:" << (localSettings.sip_iphone ? "YES" : "NO")  << endl;
2127
        cout << "    SIP firewall: " << sipFirewallToString(localSettings.sip_firewall)  << endl;
2128
        cout << "    SIP enabled:  " << (localSettings.sip_enabled ? "YES" : "NO")  << endl;
2129
    }
2130
#else
2131
    ifstream fs;
2132
 
2133
    mTemporary = false;
2134
    // First initialize the defaults
2135
    localSettings.ID = 0;
2136
    localSettings.port = 1397;
449 andreas 2137
    localSettings.ptype = "Android";
2138
    localSettings.version = VERSION_STRING();
446 andreas 2139
    localSettings.longformat = false;
2140
    localSettings.profiling = false;
2141
#ifdef __ANDROID__
2142
    localSettings.max_cache = 100;
2143
#else
2144
    localSettings.max_cache = 400;
2145
#endif
2146
    localSettings.systemSoundState = true;
2147
    localSettings.systemSound = "singleBeep.wav";
2148
    localSettings.systemSingleBeep = "singleBeep01.wav";
2149
    localSettings.systemDoubleBeep = "doubleBeep01.wav";
2150
    localSettings.ftpUser = "administrator";
2151
    localSettings.ftpPassword = "password";
2152
    localSettings.ftpSurface = "tpanel.tp4";
2153
    localSettings.sip_port = 5060;
2154
    localSettings.sip_portTLS = 0;
2155
 
2156
    // Now get the settings from file
2157
    try
2158
    {
2159
        fs.open(mCFile.c_str(), fstream::in);
2160
    }
2161
    catch (const fstream::failure e)
2162
    {
2163
        localSettings_temp = localSettings;
2164
        cerr << "TConfig::readConfig: Error on file " << mCFile << ": " << e.what() << endl;
2165
        TError::setError();
2166
        return false;
2167
    }
2168
 
2169
    for (string line; getline(fs, line);)
2170
    {
2171
        size_t pos;
2172
 
2173
        if ((pos = line.find("#")) != string::npos)
2174
        {
2175
            if (pos == 0)
2176
                line.clear();
2177
            else
2178
                line = line.substr(0, pos);
2179
        }
2180
 
2181
        if (line.empty() || line.find("=") == string::npos)
2182
            continue;
2183
 
2184
        vector<string> parts = split(line, "=", true);
2185
 
2186
        if (parts.size() == 2)
2187
        {
2188
            string left = parts[0];
2189
            string right = ltrim(parts[1]);
2190
 
2191
            if (caseCompare(left, "PORT") == 0 && !right.empty())
2192
                localSettings.port = atoi(right.c_str());
2193
            else if (caseCompare(left, "LOGFILE") == 0 && !right.empty())
2194
            {
2195
                localSettings.logFile = right;
2196
                TStreamError::setLogFileOnly(right);
2197
            }
2198
            else if (caseCompare(left, "LOGLEVEL") == 0 && !right.empty())
2199
            {
2200
                TStreamError::setLogLevel(right);
2201
                localSettings.logLevel = right;
2202
                localSettings.logLevelBits = logLevelStrToBits(right);
2203
            }
2204
            else if (caseCompare(left, "ProjectPath") == 0 && !right.empty())
2205
            {
2206
                localSettings.project = right;
2207
#ifdef __ANDROID__
2208
                TValidateFile vf;
2209
 
2210
                if (!vf.isValidFile(right))
2211
                {
2212
                    char *HOME = getenv("HOME");
2213
 
2214
                    if (HOME)
2215
                    {
2216
                        localSettings.project = HOME;
2217
                        localSettings.project += "/tpanel";
2218
                    }
2219
                }
2220
#endif
2221
            }
2222
            else if (caseCompare(left, "System") == 0 && !right.empty())
2223
                localSettings.system = atoi(right.c_str());
2224
            else if (caseCompare(left, "PanelType") == 0 && !right.empty())
2225
                localSettings.ptype = right;
2226
            else if (caseCompare(left, "Address") == 0 && !right.empty())
2227
                localSettings.server = right;
2228
            else if (caseCompare(left, "Firmware") == 0 && !right.empty())
2229
                localSettings.version = right;
2230
            else if (caseCompare(left, "LongFormat") == 0 && !right.empty())
2231
                localSettings.longformat = isTrue(right);
2232
            else if (caseCompare(left, "NoBanner") == 0 && !right.empty())
2233
                localSettings.noBanner = isTrue(right);
2234
            else if (caseCompare(left, "CertCheck") == 0 && !right.empty())
2235
                localSettings.certCheck = isTrue(right);
2236
            else if (caseCompare(left, "Channel") == 0 && !right.empty())
2237
            {
2238
                localSettings.ID = atoi(right.c_str());
2239
 
2240
                if (localSettings.ID < 10000 || localSettings.ID >= 29000)
2241
                {
2242
#ifdef __ANDROID__
2243
                    __android_log_print(ANDROID_LOG_ERROR, "tpanel", "TConfig::readConfig: Invalid port number %s", right.c_str());
2244
#else
2245
                    cerr << "TConfig::readConfig: Invalid port number " << right << endl;
2246
#endif
2247
                    localSettings.ID = 0;
2248
                }
2249
 
2250
                mChannel = localSettings.ID;
2251
            }
2252
            else if (caseCompare(left, "Scale") == 0 && !right.empty())
2253
                localSettings.scale = isTrue(right);
2254
            else if (caseCompare(left, "ToolbarForce") == 0 && !right.empty())
2255
                localSettings.tbforce = isTrue(right);
2256
            else if (caseCompare(left, "ToolbarSuppress") == 0 && !right.empty())
2257
                localSettings.tbsuppress = isTrue(right);
2258
            else if (caseCompare(left, "Profiling") == 0 && !right.empty())
2259
                localSettings.profiling = isTrue(right);
2260
            else if (caseCompare(left, "MaxButtonCache") == 0 && !right.empty())
2261
                localSettings.max_cache = atoi(right.c_str());
2262
            else if (caseCompare(left, "Password1") == 0 && !right.empty())
2263
                localSettings.password1 = right;
2264
            else if (caseCompare(left, "Password2") == 0 && !right.empty())
2265
                localSettings.password2 = right;
2266
            else if (caseCompare(left, "Password3") == 0 && !right.empty())
2267
                localSettings.password3 = right;
2268
            else if (caseCompare(left, "Password4") == 0 && !right.empty())
2269
                localSettings.password4 = right;
2270
            else if (caseCompare(left, "SystemSoundFile") == 0 && !right.empty())
2271
                localSettings.systemSound = right;
2272
            else if (caseCompare(left, "SystemSoundState") == 0 && !right.empty())
2273
                localSettings.systemSoundState = isTrue(right);
2274
            else if (caseCompare(left, "SystemSingleBeep") == 0 && !right.empty())
2275
                localSettings.systemSingleBeep = right;
2276
            else if (caseCompare(left, "SystemDoubleBeep") == 0 && !right.empty())
2277
                localSettings.systemDoubleBeep = right;
2278
            else if (caseCompare(left, "SystemVolume") == 0 && !right.empty())
2279
            {
2280
                int volume = atoi(right.c_str());
2281
 
2282
                if (volume < 0)
2283
                    volume = 0;
2284
                else if (volume > 100)
2285
                    volume = 100;
2286
 
2287
                localSettings.systemVolume = volume;
2288
            }
2289
            else if (caseCompare(left, "SystemGain") == 0 && !right.empty())
2290
            {
2291
                int gain = atoi(right.c_str());
2292
 
2293
                if (gain < 0)
2294
                    gain = 0;
2295
                else if (gain > 100)
2296
                    gain = 100;
2297
 
2298
                localSettings.systemGain = gain;
2299
            }
2300
            else if (caseCompare(left, "SystemRotationFix") == 0 && !right.empty())
2301
                localSettings.systemRotationFix = isTrue(right);
2302
            else if (caseCompare(left, "UUID") == 0 && !right.empty())
2303
                localSettings.uuid = right;
2304
            else if (caseCompare(left, "FTPuser") == 0 && !right.empty())       // FTP credentials
2305
                localSettings.ftpUser = right;
2306
            else if (caseCompare(left, "FTPpassword") == 0 && !right.empty())
2307
                localSettings.ftpPassword = right;
2308
            else if (caseCompare(left, "FTPsurface") == 0 && !right.empty())
2309
                localSettings.ftpSurface = right;
2310
            else if (caseCompare(left, "FTPpassive") == 0 && !right.empty())
2311
                localSettings.ftpPassive = isTrue(right);
2312
            else if (caseCompare(left, "FTPdownloadTime") == 0 && !right.empty())
2313
                localSettings.ftpLastDownload = atol(right.c_str());
2314
            else if (caseCompare(left, "SIP_PROXY") == 0 && !right.empty())     // SIP settings starting here
2315
                localSettings.sip_proxy = right;
2316
            else if (caseCompare(left, "SIP_PORT") == 0 && !right.empty())
2317
                localSettings.sip_port = atoi(right.c_str());
2318
            else if (caseCompare(left, "SIP_PORTTLS") == 0 && !right.empty())
2319
                localSettings.sip_portTLS = atoi(right.c_str());
2320
            else if (caseCompare(left, "SIP_STUN") == 0 && !right.empty())
2321
                localSettings.sip_stun = right;
2322
            else if (caseCompare(left, "SIP_DOMAIN") == 0 && !right.empty())
2323
                localSettings.sip_domain = right;
2324
            else if (caseCompare(left, "SIP_USER") == 0 && !right.empty())
2325
                localSettings.sip_user = right;
2326
            else if (caseCompare(left, "SIP_PASSWORD") == 0 && !right.empty())
2327
                localSettings.sip_password = right;
2328
            else if (caseCompare(left, "SIP_IPV4") == 0 && !right.empty())
2329
                localSettings.sip_ipv4 = isTrue(right);
2330
            else if (caseCompare(left, "SIP_IPV6") == 0 && !right.empty())
2331
                localSettings.sip_ipv6 = isTrue(right);
2332
            else if (caseCompare(left, "SIP_IPHONE") == 0 && !right.empty())
2333
                localSettings.sip_iphone = isTrue(right);
2334
            else if (caseCompare(left, "SIP_FIREWALL") == 0 && !right.empty())
2335
                localSettings.sip_firewall = sipFirewallStrToEnum(right);
2336
            else if (caseCompare(left, "SIP_ENABLED") == 0 && !right.empty())
2337
                localSettings.sip_enabled = isTrue(right);
482 andreas 2338
#if !defined(__ANDROID__) && !(defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_SIMULATOR))
480 andreas 2339
            else if (caseCompare(left, "APP") == 0 && !right.empty())
2340
            {
2341
                _APPS_t app;
2342
                vector<string> parts = StrSplit(right, ";");
2343
 
2344
                if (parts.size() >= 2)
2345
                {
2346
                    app.appID = parts[0];
2347
                    app.path = parts[1];
2348
                    localSettings.apps.push_back(app);
2349
                }
2350
            }
482 andreas 2351
#endif
446 andreas 2352
        }
2353
    }
2354
 
2355
    fs.close();
2356
    mInitialized = true;
2357
    TStreamError::setLogLevel(localSettings.logLevel);
2358
    TStreamError::setLogFile(localSettings.logFile);
2359
 
2360
    if (localSettings.uuid.empty())
2361
    {
2362
#ifdef __ANDROID__
2363
        QUuid qUid = QUuid::createUuid();
2364
        localSettings.uuid = qUid.toString().toStdString();
2365
#else
2366
        uuid_t uuid;
2367
        char sUUID[256];
2368
 
2369
        uuid_generate_random(uuid);
2370
        uuid_unparse_lower(uuid, sUUID);
2371
        localSettings.uuid.assign(sUUID);
2372
#endif
2373
        localSettings_temp = localSettings;
2374
        saveSettings();
2375
    }
2376
 
2377
    if (TStreamError::checkFilter(HLOG_DEBUG))
2378
    {
2379
        MSG_INFO("Selected Parameters:");
2380
        MSG_INFO("    Path to cfg.: " << localSettings.path);
2381
        MSG_INFO("    Name of cfg.: " << localSettings.name);
2382
        MSG_INFO("    Logf. enabled:" << (mLogFileEnabled ? "ENABLED" : "DISABLED"));
2383
#ifdef __ANDROID__
2384
        if (mLogFileEnabled)
2385
            MSG_INFO("    Logfile:      " << localSettings.logFile);
2386
#else
2387
        MSG_INFO("    Logfile:      " << localSettings.logFile);
2388
#endif
2389
        MSG_INFO("    LogLevel:     " << localSettings.logLevel);
2390
        MSG_INFO("    Long format:  " << (localSettings.longformat ? "YES" : "NO"));
2391
        MSG_INFO("    Project path: " << localSettings.project);
2392
#ifndef __ANDROID__
2393
        MSG_INFO("    Show banner:  " << (localSettings.noBanner ? "NO" : "YES"));
2394
#endif
2395
        MSG_INFO("    Controller:   " << localSettings.server);
2396
        MSG_INFO("    Port:         " << localSettings.port);
2397
        MSG_INFO("    Channel:      " << localSettings.ID);
2398
        MSG_INFO("    Panel type:   " << localSettings.ptype);
2399
        MSG_INFO("    Firmware ver. " << localSettings.version);
2400
        MSG_INFO("    Scaling:      " << (localSettings.scale ? "YES" : "NO"));
2401
        MSG_INFO("    Profiling:    " << (localSettings.profiling ? "YES" : "NO"));
2402
        MSG_INFO("    Button cache: " << localSettings.max_cache);
2403
        MSG_INFO("    System Sound: " << localSettings.systemSound);
2404
        MSG_INFO("    Sound state:  " << (localSettings.systemSoundState ? "ACTIVATED" : "DEACTIVATED"));
2405
        MSG_INFO("    Single beep:  " << localSettings.systemSingleBeep);
2406
        MSG_INFO("    Double beep:  " << localSettings.systemDoubleBeep);
2407
        MSG_INFO("    Volume:       " << localSettings.systemVolume);
2408
        MSG_INFO("    Gain:         " << localSettings.systemGain);
2409
        MSG_INFO("    Rotation:     " << (localSettings.systemRotationFix ? "LOCKED" : "UNLOCKED"));
2410
        MSG_INFO("    UUID:         " << localSettings.uuid);
2411
        MSG_INFO("    FTP user:     " << localSettings.ftpUser);
2412
        MSG_INFO("    FTP password: " << localSettings.ftpPassword);
2413
        MSG_INFO("    FTP surface:  " << localSettings.ftpSurface);
2414
        MSG_INFO("    FTP passive:  " << (localSettings.ftpPassive ? "YES" : "NO"));
2415
        MSG_INFO("    FTP dl. time: " << localSettings.ftpLastDownload);
2416
        MSG_INFO("    SIP proxy:    " << localSettings.sip_proxy);
2417
        MSG_INFO("    SIP port:     " << localSettings.sip_port);
2418
        MSG_INFO("    SIP TLS port: " << localSettings.sip_portTLS);
2419
        MSG_INFO("    SIP STUN:     " << localSettings.sip_stun);
2420
        MSG_INFO("    SIP doamain:  " << localSettings.sip_domain);
2421
        MSG_INFO("    SIP user:     " << localSettings.sip_user);
2422
        MSG_INFO("    SIP IPv4:     " << (localSettings.sip_ipv4 ? "YES" : "NO"));
2423
        MSG_INFO("    SIP IPv6:     " << (localSettings.sip_ipv6 ? "YES" : "NO"));
2424
        MSG_INFO("    SIP Int.Phone:" << (localSettings.sip_iphone ? "YES" : "NO"));
2425
        MSG_INFO("    SIP firewall: " << sipFirewallToString(localSettings.sip_firewall));
2426
        MSG_INFO("    SIP enabled:  " << (localSettings.sip_enabled ? "YES" : "NO"));
482 andreas 2427
#if !defined(__ANDROID__) && !(defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_SIMULATOR))
480 andreas 2428
        if (!localSettings.apps.empty())
2429
        {
2430
            vector<_APPS_t>::iterator iter;
2431
 
2432
            for (iter = localSettings.apps.begin(); iter != localSettings.apps.end(); ++iter)
2433
            {
2434
                MSG_INFO("    Appl.:        " << iter->appID << "; " << iter->path);
2435
            }
2436
        }
482 andreas 2437
#endif
446 andreas 2438
    }
2439
 
2440
    localSettings_temp = localSettings;
2441
#endif
2442
    return true;
2443
}
2444
 
2445
/**
2446
 * @brief TConfig::split splitts a string into parts.
2447
 *
2448
 * The method splitts a string into parts separated by \p seps. It puts the
2449
 * parts into a vector array.
2450
 *
2451
 * @param str           The string to split
2452
 * @param seps          The separator(s)
2453
 * @param trimEmpty     `true` = trum the parts.
2454
 *
2455
 * @return A vector array containing the parts of the string \p str.
2456
 */
2457
vector<string> TConfig::split(const string& str, const string& seps, const bool trimEmpty)
2458
{
2459
//    DECL_TRACER("TConfig::split(const string& str, const string& seps, const bool trimEmpty)");
2460
 
2461
	size_t pos = 0, mark = 0;
2462
	vector<string> parts;
2463
 
2464
	for (auto it = str.begin(); it != str.end(); ++it)
2465
	{
2466
		for (auto sepIt = seps.begin(); sepIt != seps.end(); ++sepIt)
2467
		{
2468
			if (*it == *sepIt)
2469
			{
2470
				size_t len = pos - mark;
2471
				parts.push_back(str.substr(mark, len));
2472
				mark = pos + 1;
2473
				break;
2474
			}
2475
		}
2476
 
2477
		pos++;
2478
	}
2479
 
2480
	parts.push_back(str.substr(mark));
2481
 
2482
	if (trimEmpty)
2483
	{
2484
		vector<string> nparts;
2485
 
2486
		for (auto it = parts.begin(); it != parts.end(); ++it)
2487
		{
2488
			if (it->empty())
2489
				continue;
2490
 
2491
			nparts.push_back(*it);
2492
		}
2493
 
2494
		return nparts;
2495
	}
2496
 
2497
	return parts;
2498
}
2499
 
2500
/**
2501
 * @brief TConfig::caseCompare compares 2 strings
2502
 *
2503
 * This method compares 2 strings case insensitive. This means that it ignores
2504
 * the case of the letters. For example:
2505
 *
2506
 *     BLAME
2507
 *     blame
2508
 *     Blame
2509
 *
2510
 * are all the same and would return 0, which means _equal_.
2511
 *
2512
 * @param str1  1st string to compare
2513
 * @param str2  2nd string to compare
2514
 *
2515
 * @return 0 if the strings are equal\n
2516
 * less than 0 if the byte of \p str1 is bigger than the byte of \p str2\n
2517
 * grater than 0 if the byte of \p str1 is smaller than the byte of \p str2.
2518
 */
2519
int TConfig::caseCompare(const string& str1, const string& str2)
2520
{
2521
//    DECL_TRACER("TConfig::caseCompare(const string& str1, const string& str2)");
2522
 
2523
	size_t i = 0;
2524
 
2525
	if (str1.length() != str2.length())
2526
		return ((str1.length() < str2.length()) ? -1 : 1);
2527
 
2528
	for (auto it = str1.begin(); it != str1.end(); ++it)
2529
	{
2530
		if (tolower(*it) != tolower(str2.at(i)))
2531
			return (int)(*it - str2.at(i));
2532
 
2533
		i++;
2534
	}
2535
 
2536
	return 0;
2537
}