Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

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