Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 andreas 1
/*
21 andreas 2
 * Copyright (C) 2020, 2021 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>
22
#include <unistd.h>
21 andreas 23
#include <sys/stat.h>
24
#include <sys/types.h>
22 andreas 25
#ifdef __ANDROID__
26
#include <android/log.h>
27
#include "tvalidatefile.h"
43 andreas 28
#include "tvalidatefile.h"
22 andreas 29
#endif
118 andreas 30
#include "ttpinit.h"
22 andreas 31
#include "tconfig.h"
2 andreas 32
#include "terror.h"
73 andreas 33
#include "tresources.h"
2 andreas 34
 
35
using std::string;
36
using std::ifstream;
21 andreas 37
using std::ofstream;
2 andreas 38
using std::fstream;
39
using std::vector;
21 andreas 40
using std::cout;
41
using std::cerr;
42
using std::endl;
2 andreas 43
 
116 andreas 44
bool TConfig::mInitialized{false};
45
 
21 andreas 46
/**
47
 * @struct SETTINGS
48
 * @brief The SETTINGS struct bundles the configuration options.
49
 *
50
 * This structure contains variables for all possible configuration options.
51
 * It is used by the class TConfig. Through this class it's possible to
52
 * access all configuration options.
53
 */
2 andreas 54
struct SETTINGS
55
{
21 andreas 56
    string pname{"tpanel"};     //!< Name of the program (default "tpanel")
57
    string path;                //!< The path where the configuration file is located
58
    string name;                //!< The name of the configuration file
59
    string project;             //!< The path where the original project files are located
60
    string server;              //!< The name or IP address of the server to connect
61
    int system{0};              //!< The number of the AMX system
62
    int port{0};                //!< The port number
63
    int ID{0};                  //!< the panel ID (a number starting by 10000)
64
    string ptype;               //!< The type of the panel (android, ipad, iphone, ...)
65
    string version;             //!< The "firmware" version
66
    string logFile;             //!< Optional path and name of a logfile
67
    string logLevel;            //!< The log level(s).
71 andreas 68
    uint logLevelBits;          //!< The numeric bit field of the loglevel
21 andreas 69
    bool longformat{false};     //!< TRUE = long format
70
    bool noBanner{false};       //!< Startup without showing a banner on the command line.
71
    bool certCheck{false};      //!< TRUE = Check certificate for SSL connection
24 andreas 72
    bool scale{false};          //!< TRUE = Images are scaled to fit the whole screen
120 andreas 73
    bool tbforce{false};        //!< TRUE = The toolbar is forced to display
35 andreas 74
    bool profiling{false};      //!< TRUE = The declaration traces meassure the time and write it to the log
51 andreas 75
    string password1;           //!< First panel password
76
    string password2;           //!< Second panel password
77
    string password3;           //!< Third panel password
78
    string password4;           //!< Fourth panel password
71 andreas 79
    string systemSound;         //!< name of the set system sound played on every touch.
80
    bool systemSoundState{false};   //!< TRUE = play systemsound on every touch
81
    string systemSingleBeep;    //!< name of the system sound file to play a single beep.
82
    string systemDoubleBeep;    //!< name of the system sound file to play a double beep.
112 andreas 83
    // FTP credentials
84
    string ftpUser;             //!< The username for FTP of the controller (default: administrator)
85
    string ftpPassword;         //!< The password for FTP of the controller (default: password)
115 andreas 86
    string ftpSurface;          //!< The name of the file containing the TPDesign4 file to load
116 andreas 87
    bool ftpPassive{true};      //!< If false the data port 20 is used for file transfer
115 andreas 88
    time_t ftpLastDownload{0};  //!< The timestamp of the last download
104 andreas 89
    // SIP settings
90
    string sip_proxy;           //!< The address of the SIP proxy
91
    int sip_port{5060};         //!< Initializes the port of the SIP proxy to 5060
92
    string sip_stun;            //!< STUN address
93
    string sip_domain;          //!< Local domain
94
    string sip_user;            //!< The SIP user to connect.
95
    string sip_password;        //!< The SIP password to connect. Note: This password is saved in plain text!
96
    bool sip_enabled{false};    //!< By default SIP is disabled
2 andreas 97
};
98
 
99
typedef struct SETTINGS settings_t;
21 andreas 100
static settings_t localSettings;    //!< Global defines settings used in class TConfig.
2 andreas 101
 
21 andreas 102
/**
103
 * @brief TConfig::TConfig constructor
104
 *
105
 * @param path  A path and name of a configuration file.
106
 */
2 andreas 107
TConfig::TConfig(const std::string& path)
116 andreas 108
    : mPath(path)
2 andreas 109
{
90 andreas 110
    // Initialize the possible configuration paths
111
    mCfgPaths.push_back("/etc");
112
    mCfgPaths.push_back("/etc/tpanel");
113
    mCfgPaths.push_back("/usr/etc");
114
    mCfgPaths.push_back("/usr/etc/tpanel");
115
#ifdef __APPLE__
116
    mCfgPath.push_back("/opt/local/etc");
117
    mCfgPath.push_back("/opt/local/etc/tpanel");
118
    mCfgPath.push_back("/opt/local/usr/etc");
119
    mCfgPath.push_back("/opt/local/usr/etc/tpanel");
120
#endif
121
    if (findConfig())
122
        readConfig();
2 andreas 123
}
124
 
118 andreas 125
/**
126
 * Simple method to read the configuration again. This is usefull if, for
127
 * example the configuration options changed but should not be saved. Instead
128
 * they were canceled and therefor the options are read again from file.
129
 *
130
 * @return On success it returns TRUE.
131
 */
23 andreas 132
bool TConfig::reReadConfig()
133
{
134
    return readConfig();
135
}
136
 
21 andreas 137
/**
138
 * @brief TConfig::setProgName Sets the name of the application.
139
 * @param pname The name of the application.
140
 */
2 andreas 141
void TConfig::setProgName(const std::string& pname)
142
{
116 andreas 143
    localSettings.pname = pname;
2 andreas 144
}
145
 
21 andreas 146
/**
147
 * @brief TConfig::getProgName Retrieves the prevously stored application name.
148
 * @return The name of this application.
149
 */
2 andreas 150
std::string & TConfig::getProgName()
151
{
116 andreas 152
    return localSettings.pname;
2 andreas 153
}
154
 
21 andreas 155
/**
156
 * @brief TConfig::getChannel returns the AMX channel to use.
157
 *
158
 * The AMX channels an AMX panel can use start at 10000. This method returns
159
 * the channel number found in the configuration file. If there was no
160
 * channel defination found, it returns the default channel 10001.
161
 *
162
 * @return The AMX channel number to use.
163
 */
2 andreas 164
int TConfig::getChannel()
165
{
116 andreas 166
    DECL_TRACER("TConfig::getChannel()");
167
 
168
    return localSettings.ID;
2 andreas 169
}
170
 
21 andreas 171
/**
172
 * @brief TConfig::getConfigFileName returns the name of the configuration file.
173
 *
174
 * @return The name of the configuration file.
175
 */
2 andreas 176
std::string& TConfig::getConfigFileName()
177
{
116 andreas 178
    return localSettings.name;
2 andreas 179
}
180
 
21 andreas 181
/**
182
 * @brief TConfig::getConfigPath returns the path configuration file.
183
 *
184
 * The path was defined on the command line or found by searching the standard
185
 * directories.
186
 *
187
 * @return The path of the configuration file.
188
 */
2 andreas 189
std::string& TConfig::getConfigPath()
190
{
116 andreas 191
    return localSettings.path;
2 andreas 192
}
193
 
21 andreas 194
/**
195
 * @brief TConfig::getController returns the network name or IP address of the AMX controller.
196
 *
197
 * The network name or the IP address was read from the configuration file.
198
 *
199
 * @return The network name of the AMX controller.
200
 */
2 andreas 201
std::string& TConfig::getController()
202
{
116 andreas 203
    DECL_TRACER("TConfig::getController()");
204
 
205
    return localSettings.server;
2 andreas 206
}
207
 
21 andreas 208
/**
209
 * @brief TConfig::getSystem return the AMX system number.
210
 *
211
 * This number was read from the configuration file. If there was no system
212
 * number defined in the configuration file, then the default number 0 is
213
 * returned.
214
 *
215
 * @return The AMX system number.
216
 */
11 andreas 217
int TConfig::getSystem()
218
{
116 andreas 219
    DECL_TRACER("TConfig::getSystem()");
220
 
11 andreas 221
    return localSettings.system;
222
}
223
 
21 andreas 224
/**
225
 * @brief TConfig::getFirmVersion returns the version of the firmware.
226
 *
227
 * This option was read from the configuration file. There can be any version
228
 * number defined. But you must keep in mind, that the AMX controller may not
229
 * accept any number. If there was no version number defined, the standard
230
 * version number 1.0 is returned.
231
 *
232
 * @return The firmware version of this panel.
233
 */
2 andreas 234
std::string& TConfig::getFirmVersion()
235
{
116 andreas 236
    DECL_TRACER("TConfig::getFirmVersion()");
237
 
238
    return localSettings.version;
2 andreas 239
}
240
 
21 andreas 241
/**
242
 * @brief TConfig::getLogFile the path and name of a logfile.
243
 *
244
 * If there is a logfile name defined in the configuration file, it is used
245
 * to write messages there. It depends on the _log level_ what is logged.
246
 *
247
 * @return The path and name of a logfile.
248
 */
2 andreas 249
std::string& TConfig::getLogFile()
250
{
116 andreas 251
    return localSettings.logFile;
2 andreas 252
}
253
 
21 andreas 254
/**
255
 * @brief TConfig::getLogLevel returns the defined log level.
256
 *
51 andreas 257
 * The loglevel can consist of the following values:
21 andreas 258
 *
259
 *     NONE         Logs nothing (default for Android)
260
 *     INFO         Logs only informations
261
 *     WARNING      Logs only warnings
51 andreas 262
 *     ERROR        Logs only errors
21 andreas 263
 *     TRACE        Logs only trace messages
264
 *     DEBUG        Logs only debug messages
265
 *     PROTOCOL     Logs only INFO and ERROR (default if NOT Android)
266
 *     ALL          Logs everything
267
 *
268
 * All log levels can be combined by concatenating them with the | symbol.
269
 *
270
 * @return The log level(s) as a string.
271
 */
2 andreas 272
string& TConfig::getLogLevel()
273
{
116 andreas 274
    return localSettings.logLevel;
2 andreas 275
}
276
 
21 andreas 277
/**
59 andreas 278
 * @brief TConfig::getLogLevelBits
279
 *
280
 * Returns the raw bit field defining the loglevels selected.
281
 *
282
 * @return The bit field of representing the selected log levels.
283
 */
284
uint TConfig::getLogLevelBits()
285
{
116 andreas 286
    DECL_TRACER("TConfig::getLogLevelBits()");
287
 
59 andreas 288
    return localSettings.logLevelBits;
289
}
290
/**
21 andreas 291
 * @brief TConfig::getPanelType the AMX type name of the panel.
292
 *
293
 * The type name of the panel is defined in the configuration file. If this
294
 * option was not defined, the default panel _android_ is returned.
295
 *
296
 * @return The type name of the panel.
297
 */
2 andreas 298
std::string& TConfig::getPanelType()
299
{
116 andreas 300
    DECL_TRACER("TConfig::getPanelType()");
301
 
302
    return localSettings.ptype;
2 andreas 303
}
304
 
21 andreas 305
/**
306
 * @brief TConfig::getPort returnes the AMX port number to connect to.
307
 *
308
 * The port number can be defined in the configuration file. If there is no
309
 * configuration the default number 1319 is returned.
310
 *
311
 * @return The AMX network port number.
312
 */
2 andreas 313
int TConfig::getPort()
314
{
116 andreas 315
    DECL_TRACER("TConfig::getPort()");
316
 
317
    return localSettings.port;
2 andreas 318
}
319
 
21 andreas 320
/**
321
 * @brief TConfig::getProjectPath returns the path to the AMX configuration files.
322
 *
323
 * The path was read from the configuration file. This path contains all the
324
 * files needed to display the elements of the surface.
325
 *
326
 * @return The path to the AMX configuration files.
327
 */
71 andreas 328
string& TConfig::getProjectPath()
2 andreas 329
{
116 andreas 330
    return localSettings.project;
2 andreas 331
}
332
 
112 andreas 333
 
71 andreas 334
string TConfig::getSystemPath(SYSTEMRESOURCE_t sres)
335
{
116 andreas 336
    DECL_TRACER("TConfig::getSystemPath(SYSTEMRESOURCE_t sres)");
337
 
71 andreas 338
    string p;
339
 
340
    switch(sres)
341
    {
342
        case BORDERS:   p = "/borders"; break;
343
        case FONTS:     p = "/fonts"; break;
344
        case IMAGES:    p = "/images"; break;
345
        case SLIDERS:   p = "/sliders"; break;
346
        case SOUNDS:    p = "/sounds"; break;
347
        default:
348
            p.clear();
349
    }
350
 
351
    return localSettings.project + "/__system/graphics" + p;
352
}
353
 
23 andreas 354
bool TConfig::saveLogFile(const string &file)
355
{
356
    DECL_TRACER("TConfig::saveLogFile(const string &file)");
357
 
358
    if (file.empty() || localSettings.logFile.compare(file) == 0)
359
        return false;
360
 
361
    localSettings.logFile = file;
362
    return true;
363
}
364
 
365
bool TConfig::saveLogLevel(const string &level)
366
{
367
    DECL_TRACER("TConfig::saveLogLevel(const string &level)");
368
 
59 andreas 369
    if (level.find(SLOG_NONE) == string::npos && level.find(SLOG_INFO) == string::npos && level.find(SLOG_WARNING) == string::npos &&
370
            level.find(SLOG_ERROR) == string::npos && level.find(SLOG_TRACE) == string::npos && level.find(SLOG_DEBUG) == string::npos &&
371
            level.find(SLOG_PROTOCOL) == string::npos && level.find(SLOG_ALL) == string::npos)
23 andreas 372
        return false;
373
 
374
    localSettings.logLevel = level;
59 andreas 375
    localSettings.logLevelBits = logLevelStrToBits(level);
376
    MSG_INFO("New log level: " << level);
23 andreas 377
    return true;
378
}
379
 
59 andreas 380
bool TConfig::saveLogLevel(uint level)
381
{
382
    DECL_TRACER("TConfig::saveLogLevel(uint level)");
383
 
384
    if (level != 0 && !(level&HLOG_INFO) && !(level&HLOG_WARNING) &&
385
            !(level&HLOG_ERROR) && !(level&HLOG_TRACE) && !(level&HLOG_DEBUG))
386
        return false;
387
 
388
    localSettings.logLevelBits = level;
389
    localSettings.logLevel = logLevelBitsToString(level);
390
    MSG_INFO("New log level from bits: " << localSettings.logLevel);
391
    return true;
392
}
393
 
23 andreas 394
bool TConfig::saveChannel(int channel)
395
{
396
    DECL_TRACER("TConfig::saveChannel(int channel)");
397
 
398
    if (channel < 10000 || channel > 12000)
399
        return false;
400
 
401
    localSettings.ID = channel;
402
    return true;
403
}
404
 
405
bool TConfig::saveController(const string &cnt)
406
{
407
    DECL_TRACER("TConfig::saveController(const string &cnt)");
408
 
409
    localSettings.server = cnt;
410
    return true;
411
}
412
 
413
bool TConfig::savePanelType(const string &pt)
414
{
415
    DECL_TRACER("TConfig::savePanelType(const string &pt)");
416
 
417
    localSettings.ptype = pt;
418
    return true;
419
}
420
 
421
bool TConfig::savePort(int port)
422
{
423
    DECL_TRACER("TConfig::savePort(int port)");
424
 
425
    if (port < 1024 || port > 32767)
426
        return false;
427
 
428
    localSettings.port = port;
429
    return true;
430
}
431
 
432
bool TConfig::saveProjectPath(const string &path)
433
{
434
    DECL_TRACER("TConfig::saveProjectPath(const string &path)");
435
 
436
    if (path.empty())
437
        return false;
438
 
439
    localSettings.project = path;
440
    return true;
441
}
442
 
443
void TConfig::saveFormat(bool format)
444
{
445
    DECL_TRACER("TConfig::saveFormat(bool format)");
446
 
447
    localSettings.longformat = format;
448
}
449
 
24 andreas 450
void TConfig::saveScale(bool scale)
451
{
452
    DECL_TRACER("TConfig::saveScale(bool scale)");
453
 
454
    localSettings.scale = scale;
455
}
456
 
118 andreas 457
void TConfig::saveBanner(bool banner)
458
{
459
    DECL_TRACER("TConfig::saveBanner(bool banner)");
460
 
461
    localSettings.noBanner = banner;
462
}
463
 
120 andreas 464
void TConfig::saveToolbarForce(bool tb)
465
{
466
    DECL_TRACER("TConfig::saveToolbarForce(bool tb)");
467
 
468
    localSettings.tbforce = tb;
469
}
470
 
35 andreas 471
void TConfig::saveProfiling(bool prof)
472
{
116 andreas 473
    DECL_TRACER("TConfig::saveProfiling(bool prof)");
474
 
35 andreas 475
    localSettings.profiling = prof;
476
}
477
 
51 andreas 478
void TConfig::savePassword1(const std::string& pw)
479
{
116 andreas 480
    DECL_TRACER("TConfig::savePassword1(const std::string& pw)");
481
 
51 andreas 482
    localSettings.password1 = pw;
483
}
484
 
485
void TConfig::savePassword2(const std::string& pw)
486
{
116 andreas 487
    DECL_TRACER("TConfig::savePassword2(const std::string& pw)");
488
 
51 andreas 489
    localSettings.password2 = pw;
490
}
491
 
492
void TConfig::savePassword3(const std::string& pw)
493
{
116 andreas 494
    DECL_TRACER("TConfig::savePassword3(const std::string& pw)");
495
 
51 andreas 496
    localSettings.password3 = pw;
497
}
498
 
499
void TConfig::savePassword4(const std::string& pw)
500
{
116 andreas 501
    DECL_TRACER("TConfig::savePassword4(const std::string& pw)");
502
 
51 andreas 503
    localSettings.password4 = pw;
504
}
505
 
71 andreas 506
void TConfig::saveSystemSoundFile(const std::string& snd)
507
{
116 andreas 508
    DECL_TRACER("TConfig::saveSystemSoundFile(const std::string& snd)");
509
 
71 andreas 510
    localSettings.systemSound = snd;
511
}
512
 
513
void TConfig::saveSystemSoundState(bool state)
514
{
116 andreas 515
    DECL_TRACER("TConfig::saveSystemSoundState(bool state)");
516
 
71 andreas 517
    localSettings.systemSoundState = state;
518
}
519
 
112 andreas 520
void TConfig::saveFtpUser(const string& user)
521
{
116 andreas 522
    DECL_TRACER("TConfig::saveFtpUser(const string& user)");
523
 
112 andreas 524
    localSettings.ftpUser = user;
525
}
526
 
527
void TConfig::saveFtpPassword(const string& pw)
528
{
116 andreas 529
    DECL_TRACER("TConfig::saveFtpPassword(const string& pw)");
530
 
112 andreas 531
    localSettings.ftpPassword = pw;
532
}
533
 
115 andreas 534
void TConfig::saveFtpSurface(const string& fname)
535
{
116 andreas 536
    DECL_TRACER("TConfig::saveFtpSurface(const string& fname)");
537
 
115 andreas 538
    localSettings.ftpSurface = fname;
539
}
540
 
116 andreas 541
void TConfig::saveFtpPassive(bool mode)
542
{
543
    DECL_TRACER("TConfig::saveFtpPassive(bool mode)");
544
 
545
    localSettings.ftpPassive = mode;
546
}
547
 
115 andreas 548
void TConfig::saveFtpDownloadTime(time_t t)
549
{
116 andreas 550
    DECL_TRACER("TConfig::saveFtpDownloadTime(time_t t)");
551
 
115 andreas 552
    localSettings.ftpLastDownload = t;
553
}
554
 
104 andreas 555
std::string& TConfig::getSIPproxy()
556
{
116 andreas 557
    DECL_TRACER("TConfig::getSIPproxy()");
558
 
104 andreas 559
    return localSettings.sip_proxy;
560
}
561
 
562
void TConfig::setSIPproxy(const std::string& address)
563
{
116 andreas 564
    DECL_TRACER("TConfig::setSIPproxy(const std::string& address)");
565
 
104 andreas 566
    localSettings.sip_proxy = address;
567
}
568
 
569
int TConfig::getSIPport()
570
{
116 andreas 571
    DECL_TRACER("TConfig::getSIPport()");
572
 
104 andreas 573
    return localSettings.sip_port;
574
}
575
 
576
void TConfig::setSIPport(int port)
577
{
116 andreas 578
    DECL_TRACER("TConfig::setSIPport(int port)");
579
 
104 andreas 580
    localSettings.sip_port = port;
581
}
582
 
583
std::string& TConfig::getSIPstun()
584
{
116 andreas 585
    DECL_TRACER("TConfig::getSIPstun()");
586
 
104 andreas 587
    return localSettings.sip_stun;
588
}
589
 
590
void TConfig::setSIPstun(const std::string& address)
591
{
116 andreas 592
    DECL_TRACER("TConfig::setSIPstun(const std::string& address)");
593
 
104 andreas 594
    localSettings.sip_stun = address;
595
}
596
 
597
std::string& TConfig::getSIPdomain()
598
{
116 andreas 599
    DECL_TRACER("TConfig::getSIPdomain()");
600
 
104 andreas 601
    return localSettings.sip_domain;
602
}
603
 
604
void TConfig::setSIPdomain(const std::string& domain)
605
{
116 andreas 606
    DECL_TRACER("TConfig::setSIPdomain(const std::string& domain)");
607
 
104 andreas 608
    localSettings.sip_domain = domain;
609
}
610
 
611
std::string& TConfig::getSIPuser()
612
{
116 andreas 613
    DECL_TRACER("TConfig::getSIPuser()");
614
 
104 andreas 615
    return localSettings.sip_user;
616
}
617
 
618
void TConfig::setSIPuser(const std::string& user)
619
{
116 andreas 620
    DECL_TRACER("TConfig::setSIPuser(const std::string& user)");
621
 
104 andreas 622
    localSettings.sip_user = user;
623
}
624
 
625
std::string& TConfig::getSIPpassword()
626
{
116 andreas 627
    DECL_TRACER("TConfig::getSIPpassword()");
628
 
104 andreas 629
    return localSettings.sip_password;
630
}
631
 
632
void TConfig::setSIPpassword(const std::string& pw)
633
{
116 andreas 634
    DECL_TRACER("TConfig::setSIPpassword(const std::string& pw)");
635
 
104 andreas 636
    localSettings.sip_password = pw;
637
}
638
 
639
bool TConfig::getSIPstatus()
640
{
116 andreas 641
    DECL_TRACER("TConfig::getSIPstatus()");
642
 
104 andreas 643
    return localSettings.sip_enabled;
644
}
645
 
646
void TConfig::setSIPstatus(bool state)
647
{
116 andreas 648
    DECL_TRACER("TConfig::setSIPstatus(bool state)");
649
 
104 andreas 650
    localSettings.sip_enabled = state;
651
}
652
 
23 andreas 653
bool TConfig::saveSettings()
654
{
655
    DECL_TRACER("TConfig::saveSettings()");
656
 
657
    try
658
    {
659
        string fname = localSettings.path + "/" + localSettings.name;
660
        ofstream file(fname);
661
        string lines = "LogFile=" + localSettings.logFile + "\n";
662
        lines += "LogLevel=" + localSettings.logLevel + "\n";
663
        lines += "ProjectPath=" + localSettings.project + "\n";
664
        lines += string("NoBanner=") + (localSettings.noBanner ? "true" : "false") + "\n";
120 andreas 665
        lines += string("ToolbarForce=") + (localSettings.tbforce ? "true" : "false") + "\n";
23 andreas 666
        lines += string("LongFormat=") + (localSettings.longformat ? "true" : "false") + "\n";
667
        lines += "Address=" + localSettings.server + "\n";
668
        lines += "Port=" + std::to_string(localSettings.port) + "\n";
669
        lines += "Channel=" + std::to_string(localSettings.ID) + "\n";
670
        lines += "System=" + std::to_string(localSettings.system) + "\n";
671
        lines += "PanelType=" + localSettings.ptype + "\n";
672
        lines += "Firmware=" + localSettings.version + "\n";
673
        lines += string("CertCheck=") + (localSettings.certCheck ? "true" : "false") + "\n";
24 andreas 674
        lines += string("Scale=") + (localSettings.scale ? "true" : "false") + "\n";
35 andreas 675
        lines += string("Profiling=") + (localSettings.profiling ? "true" : "false") + "\n";
51 andreas 676
        lines += string("Password1=") + localSettings.password1 + "\n";
677
        lines += string("Password2=") + localSettings.password2 + "\n";
678
        lines += string("Password3=") + localSettings.password3 + "\n";
679
        lines += string("Password4=") + localSettings.password4 + "\n";
71 andreas 680
        lines += string("SystemSoundFile=") + localSettings.systemSound + "\n";
681
        lines += string("SystemSoundState=") + (localSettings.systemSoundState ? "ON" : "OFF") + "\n";
682
        lines += string("SystemSingleBeep=") + localSettings.systemSingleBeep + "\n";
683
        lines += string("SystemDoubleBeep=") + localSettings.systemDoubleBeep + "\n";
112 andreas 684
        // FTP credentials
685
        lines += string("FTPuser=") + localSettings.ftpUser + "\n";
686
        lines += string("FTPpassword=") + localSettings.ftpPassword + "\n";
115 andreas 687
        lines += string("FTPsurface=") + localSettings.ftpSurface + "\n";
116 andreas 688
        lines += string("FTPpassive=") + (localSettings.ftpPassive ? "true" : "false") + "\n";
115 andreas 689
        lines += string("FTPdownloadTime=") + std::to_string(localSettings.ftpLastDownload) + "\n";
104 andreas 690
        // SIP settings
116 andreas 691
        lines += string("SIP_DOMAIN=") + localSettings.sip_domain + "\n";
692
        lines += string("SIP_PROXY=") + localSettings.sip_password + "\n";
693
        lines += string("SIP_PORT=") + std::to_string(localSettings.sip_port) + "\n";
694
        lines += string("SIP_STUN=") + localSettings.sip_stun + "\n";
695
        lines += string("SIP_USER=") + localSettings.sip_user + "\n";
696
        lines += string("SIP_PASSWORD=") + localSettings.sip_password + "\n";
697
        lines += string("SIP_ENABLED=") + (localSettings.sip_enabled ? "true" : "false") + "\n";
23 andreas 698
        file.write(lines.c_str(), lines.size());
699
        file.close();
59 andreas 700
        MSG_INFO("Actual log level: " << localSettings.logLevel);
23 andreas 701
    }
702
    catch (std::exception& e)
703
    {
704
        MSG_ERROR("Couldn't write configs: " << e.what());
705
        return false;
706
    }
707
 
116 andreas 708
    TError::Current()->setLogLevel(localSettings.logLevel);
23 andreas 709
    TError::Current()->setLogFile(localSettings.logFile);
710
    return true;
711
}
712
 
21 andreas 713
/**
714
 * @brief TConfig::isLongFormat defines the format in the logfile.
715
 *
716
 * If this returns `true` the format in the logfile is a long format. This
717
 * means, that in front of each message is an additional timestamp.
718
 *
719
 * @return `true` = long format, `false` = short format (default).
720
 */
2 andreas 721
bool TConfig::isLongFormat()
722
{
116 andreas 723
    return localSettings.longformat;
2 andreas 724
}
725
 
21 andreas 726
/**
727
 * @brief TConfig::showBanner defines whether the banner should be showed or not.
728
 *
729
 * If this method returns `false` the banner on startup is not displayed.
730
 *
731
 * @return `true` = display the banner (default), `false` = show no banner.
732
 */
2 andreas 733
bool TConfig::showBanner()
734
{
116 andreas 735
    DECL_TRACER("TConfig::showBanner()");
736
 
737
    return !localSettings.noBanner;
2 andreas 738
}
739
 
21 andreas 740
/**
24 andreas 741
 * @brief TConfig::getScale returns the scale setting
742
 *
743
 * If this is set to TRUE, all images are scaled to fit the screen.
744
 *
745
 * @return scale state
746
 */
747
bool TConfig::getScale()
748
{
116 andreas 749
    DECL_TRACER("TConfig::getScale()");
750
 
24 andreas 751
    return localSettings.scale;
752
}
753
 
120 andreas 754
bool TConfig::getToolbarForce()
755
{
756
    DECL_TRACER("TConfig::getToolbarForce()");
757
 
758
    return localSettings.tbforce;
759
}
760
 
35 andreas 761
bool TConfig::getProfiling()
762
{
763
    return localSettings.profiling;
764
}
765
 
51 andreas 766
string & TConfig::getPassword1()
767
{
116 andreas 768
    DECL_TRACER("TConfig::getPassword1()");
769
 
51 andreas 770
    return localSettings.password1;
771
}
772
 
773
string & TConfig::getPassword2()
774
{
116 andreas 775
    DECL_TRACER("TConfig::getPassword2()");
776
 
51 andreas 777
    return localSettings.password2;
778
}
779
 
780
string & TConfig::getPassword3()
781
{
116 andreas 782
    DECL_TRACER("TConfig::getPassword3()");
783
 
51 andreas 784
    return localSettings.password3;
785
}
786
 
787
string & TConfig::getPassword4()
788
{
116 andreas 789
    DECL_TRACER("TConfig::getPassword4()");
790
 
51 andreas 791
    return localSettings.password4;
792
}
793
 
71 andreas 794
string & TConfig::getSystemSound()
795
{
116 andreas 796
    DECL_TRACER("TConfig::getSystemSound()");
797
 
71 andreas 798
    return localSettings.systemSound;
799
}
800
 
801
bool TConfig::getSystemSoundState()
802
{
116 andreas 803
    DECL_TRACER("TConfig::getSystemSoundState()");
804
 
71 andreas 805
    return localSettings.systemSoundState;
806
}
807
 
808
string& TConfig::getSingleBeepSound()
809
{
116 andreas 810
    DECL_TRACER("TConfig::getSingleBeepSound()");
811
 
71 andreas 812
    return localSettings.systemSingleBeep;
813
}
814
 
815
string& TConfig::getDoubleBeepSound()
816
{
116 andreas 817
    DECL_TRACER("TConfig::getDoubleBeepSound()");
818
 
71 andreas 819
    return localSettings.systemDoubleBeep;
820
}
821
 
112 andreas 822
string& TConfig::getFtpUser()
823
{
116 andreas 824
    DECL_TRACER("TConfig::getFtpUser()");
825
 
112 andreas 826
    return localSettings.ftpUser;
827
}
828
 
829
string& TConfig::getFtpPassword()
830
{
116 andreas 831
    DECL_TRACER("TConfig::getFtpPassword()");
832
 
112 andreas 833
    return localSettings.ftpPassword;
834
}
835
 
115 andreas 836
string& TConfig::getFtpSurface()
837
{
116 andreas 838
    DECL_TRACER("TConfig::getFtpSurface()");
839
 
115 andreas 840
    return localSettings.ftpSurface;
841
}
842
 
116 andreas 843
bool TConfig::getFtpPassive()
844
{
845
    DECL_TRACER("TConfig::getFtpPassive()");
846
 
847
    return localSettings.ftpPassive;
848
}
849
 
115 andreas 850
time_t TConfig::getFtpDownloadTime()
851
{
116 andreas 852
    DECL_TRACER("TConfig::getFtpDownloadTime()");
853
 
115 andreas 854
    return localSettings.ftpLastDownload;
855
}
856
 
24 andreas 857
/**
71 andreas 858
 * Checks a string if it contains a word which may be interpreted as a
859
 * boolean TRUE.
860
 *
861
 * @param boolean   A string containg a word.
862
 *
863
 * @return If the string \p boolean contains a word that can be interpreted as
864
 * a boolean TRUE, it returns TRUE. In any other case it returns FALSE.
865
 */
866
bool TConfig::isTrue(const string& boolean)
867
{
868
    if (caseCompare(boolean, "1") == 0 || caseCompare(boolean, "yes") == 0 ||
869
        caseCompare(boolean, "true") == 0 || caseCompare(boolean, "on") == 0)
870
        return true;
871
 
872
    return false;
873
}
874
 
875
/**
21 andreas 876
 * @brief TConfig::certCheck check the certificate if the connection is encrypted.
877
 *
878
 * Currently not implemented!
879
 *
880
 * @return `true` = check the certificate, `false` = accept any certificate (default).
881
 */
882
bool TConfig::certCheck()
883
{
884
    return localSettings.certCheck;
885
}
886
 
887
/**
59 andreas 888
 * @brief TConfig::logLevelStrToBits
889
 * Converts a string containing one or more loglevels into a bit field.
890
 * @param level A string containing the log levels
891
 * @return A bit field representing the log levels.
892
 */
893
uint TConfig::logLevelStrToBits(const string& level)
894
{
895
    uint l = 0;
896
 
897
    if (level.find("INFO") != string::npos)
898
        l |= HLOG_INFO;
899
 
900
    if (level.find("WARNING") != string::npos)
901
        l |= HLOG_WARNING;
902
 
903
    if (level.find("ERROR") != string::npos)
904
        l |= HLOG_ERROR;
905
 
906
    if (level.find("TRACE") != string::npos)
907
        l |= HLOG_TRACE;
908
 
909
    if (level.find("DEBUG") != string::npos)
910
        l |= HLOG_DEBUG;
911
 
912
    if (level.find("PROTOCOL") != string::npos)
71 andreas 913
        l |= HLOG_PROTOCOL;
59 andreas 914
 
915
    if (level.find("ALL") != string::npos)
916
        l = HLOG_ALL;
917
 
918
    return l;
919
}
920
 
921
string TConfig::logLevelBitsToString(uint level)
922
{
923
    string l;
924
 
925
    if (level == 0)
926
    {
927
        l = SLOG_NONE;
928
        return l;
929
    }
930
 
931
    if (level & HLOG_INFO)
932
    {
933
        if (l.length() > 0)
934
            l.append("|");
935
 
936
        l.append(SLOG_INFO);
937
    }
938
 
939
    if (level & HLOG_WARNING)
940
    {
941
        if (l.length() > 0)
942
            l.append("|");
943
 
944
        l.append(SLOG_WARNING);
945
    }
946
 
947
    if (level & HLOG_ERROR)
948
    {
949
        if (l.length() > 0)
950
            l.append("|");
951
 
952
        l.append(SLOG_ERROR);
953
    }
954
 
955
    if (level & HLOG_TRACE)
956
    {
957
        if (l.length() > 0)
958
            l.append("|");
959
 
960
        l.append(SLOG_TRACE);
961
    }
962
 
963
    if (level & HLOG_DEBUG)
964
    {
965
        if (l.length() > 0)
966
            l.append("|");
967
 
968
        l.append(SLOG_DEBUG);
969
    }
970
 
971
    return l;
972
}
118 andreas 973
 
974
string TConfig::makeConfigDefault(const std::string& log, const std::string& project)
975
{
976
    string content = "LogFile=" + log + "\n";
977
    content += "LogLevel=NONE\n";
978
    content += "ProjectPath=" + project + "\n";
979
    content += "LongFormat=false\n";
980
    content += "Address=0.0.0.0\n";
981
    content += "Port=1319\n";
982
    content += "Channel=10001\n";
983
    content += "PanelType=Android\n";
984
    content += string("Firmware=") + VERSION_STRING() + "\n";
985
    content += "Scale=true\n";
120 andreas 986
    content += "ToolbarForce=false\n";
118 andreas 987
    content += "Profiling=false\n";
988
    content += "Password1=1988\n";
989
    content += "Password2=1988\n";
990
    content += "Password3=1988\n";
991
    content += "Password4=1988\n";
992
    content += "SystemSoundFile=singleBeep.wav\n";
993
    content += "SystemSoundState=ON\n";
994
    content += "SystemSingleBeep=singleBeep01.wav\n";
995
    content += "SystemDoubleBeep=doubleBeep01.wav\n";
996
    content += "FTPuser=administrator\n";
997
    content += "FTPpassword=password\n";
998
    content += "FTPsurface=tpanel.tp4\n";
999
    content += "FTPpassive=true\n";
1000
    content += "FTPdownloadTime=0\n";
1001
    content += "SIP_PORT=" + std::to_string(localSettings.sip_port) + "\n";
1002
 
1003
    return content;
1004
}
1005
 
59 andreas 1006
/**
21 andreas 1007
 * @brief TConfig::findConfig search for the location of the configuration file.
1008
 *
1009
 * If there was no configuration file given on the command line, this method
1010
 * searches for a configuration file on a few standard directories. This are:
1011
 *
1012
 *     /etc/tpanel.conf
1013
 *     /etc/tpanel/tpanel.conf
1014
 *     /usr/etc/tpanel.conf
1015
 *     $HOME/.tpanel.conf
1016
 *
1017
 * On macOS the following additional directories are searched:
1018
 *
1019
 *     /opt/local/etc/tpanel.conf
1020
 *     /opt/local/etc/tpanel/tpanel.conf
1021
 *     /opt/local/usr/etc/tpanel.conf
1022
 *
1023
 * @return On success `true`, otherwise `false`.
1024
 */
2 andreas 1025
bool TConfig::findConfig()
1026
{
90 andreas 1027
    char *HOME = nullptr;
1028
    string sFileName;
22 andreas 1029
 
90 andreas 1030
    if (!mPath.empty())
1031
    {
1032
        size_t pos = mPath.find_last_of("/");
2 andreas 1033
 
90 andreas 1034
        if (pos != string::npos)
1035
        {
1036
            localSettings.path = mPath.substr(0, pos);
1037
            localSettings.name = mPath.substr(pos+1);
1038
            mCFile = mPath;
1039
            return !mCFile.empty();
1040
        }
2 andreas 1041
 
90 andreas 1042
        localSettings.name = mPath;
1043
        mCFile = mPath;
1044
        return !mCFile.empty();
1045
    }
2 andreas 1046
 
90 andreas 1047
    localSettings.name = "tpanel.conf";
51 andreas 1048
    localSettings.password1 = "1988";
1049
    localSettings.password2 = "1988";
1050
    localSettings.password3 = "1988";
1051
    localSettings.password4 = "1988";
71 andreas 1052
    localSettings.systemSound = "singleBeep.wav";
1053
    localSettings.systemSoundState = true;
1054
    localSettings.systemSingleBeep = "singleBeep01.wav";
1055
    localSettings.systemDoubleBeep = "doubleBeep01.wav";
112 andreas 1056
    localSettings.ftpUser = "administrator";
1057
    localSettings.ftpPassword = "password";
115 andreas 1058
    localSettings.ftpSurface = "tpanel.tp4";
21 andreas 1059
#ifdef __ANDROID__
22 andreas 1060
    std::stringstream s;
1061
    TValidateFile vf;
1062
    HOME = getenv("HOME");
2 andreas 1063
 
22 andreas 1064
    if (!HOME || !*HOME)
21 andreas 1065
    {
43 andreas 1066
        s << "Error: Environment variable HOME does not exist!";
22 andreas 1067
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", s.str().c_str());
1068
        TError::setErrorMsg(s.str());
21 andreas 1069
        return false;
1070
    }
1071
 
22 andreas 1072
    localSettings.path = HOME;
1073
 
88 andreas 1074
    if (!vf.isValidDir(localSettings.path))
21 andreas 1075
    {
22 andreas 1076
        s << "Error: Path " << localSettings.path << " does not exist!";
1077
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", s.str().c_str());
1078
        TError::setErrorMsg(s.str());
21 andreas 1079
        return false;
1080
    }
1081
 
22 andreas 1082
    sFileName = localSettings.path + "/" + localSettings.name;
21 andreas 1083
 
22 andreas 1084
    if (access(sFileName.c_str(), F_OK) == -1)    // Does the configuration file exist?
21 andreas 1085
    {                                       // No, than create it and also the directory structure
1086
        try
1087
        {
1088
            ofstream cfg(sFileName);
1089
 
118 andreas 1090
            string content = makeConfigDefault(localSettings.path + "/tpanel.log", localSettings.path + "/tpanel");
21 andreas 1091
            cfg.write(content.c_str(), content.size());
1092
            cfg.close();
1093
 
1094
            string path = localSettings.path + "/tpanel";
22 andreas 1095
            TTPInit init(path);
21 andreas 1096
        }
1097
        catch (std::exception& e)
1098
        {
23 andreas 1099
            s << "Error: " << e.what();
22 andreas 1100
            __android_log_print(ANDROID_LOG_ERROR, "tpanel" , "%s", s.str().c_str());
21 andreas 1101
            TError::setErrorMsg(TERRERROR, string("Error: ") + e.what());
1102
            return false;
1103
        }
1104
    }
1105
#else
90 andreas 1106
    if (!(HOME = getenv("HOME")))
116 andreas 1107
        MSG_ERROR("TConfig::findConfig: No environment variable HOME!");
2 andreas 1108
 
90 andreas 1109
    vector<string>::iterator iter;
1110
    bool found = false;
2 andreas 1111
 
90 andreas 1112
    for (iter = mCfgPaths.begin(); iter != mCfgPaths.end(); ++iter)
1113
    {
1114
        string f = *iter + "/tpanel.conf";
1115
 
1116
        if (!access(f.c_str(), R_OK))
1117
        {
1118
            sFileName = f;
1119
            localSettings.path = *iter;
113 andreas 1120
            found = true;
90 andreas 1121
            break;
1122
        }
1123
    }
1124
 
1125
    // The local configuration file has precedence over the global one.
1126
    if (HOME)
1127
    {
1128
        string f = HOME;
113 andreas 1129
#ifndef __ANDROID__
90 andreas 1130
        f += "/.tpanel.conf";
113 andreas 1131
#else
1132
        f += "/tpanel.conf";
1133
#endif
90 andreas 1134
        if (!access(f.data(), R_OK))
1135
        {
1136
            sFileName = f;
1137
            localSettings.path = HOME;
1138
            found = true;
1139
        }
1140
    }
1141
 
1142
    if (!found)
1143
    {
118 andreas 1144
        MSG_WARNING("This seems to be the first start because of missing configuration file. Will try to create a default one ...");
1145
 
1146
        if (HOME)
1147
        {
1148
            localSettings.path = HOME;
1149
            sFileName = string(HOME) + "/.tpanel.conf";
1150
 
1151
            try
1152
            {
1153
                ofstream cfg(sFileName);
1154
 
1155
                string content = makeConfigDefault(localSettings.path + "/tpanel.log", localSettings.path + "/tpanel");
1156
                cfg.write(content.c_str(), content.size());
1157
                cfg.close();
1158
 
1159
                string path = localSettings.path + "/tpanel";
1160
                TTPInit init(path);
1161
            }
1162
            catch (std::exception& e)
1163
            {
1164
                cerr << "Error: " << e.what();
1165
                TError::setErrorMsg(TERRERROR, string("Error: ") + e.what());
1166
                return false;
1167
            }
1168
        }
1169
        else
1170
        {
1171
            MSG_ERROR("TConfig::findConfig: Can't find any configuration file!");
1172
            TError::setError();
1173
            sFileName.clear();
1174
            localSettings.name.clear();
1175
            localSettings.path.clear();
1176
        }
90 andreas 1177
    }
21 andreas 1178
#endif
90 andreas 1179
    mCFile = sFileName;
1180
    return !sFileName.empty();
2 andreas 1181
}
1182
 
21 andreas 1183
/**
1184
 * @brief TConfig::readConfig reads a config file.
1185
 *
1186
 * This method reads a config file and stores the known options into the
1187
 * struct localSettings.
1188
 *
1189
 * @return `true` on success.\n
1190
 * Returns `false` on error and sets the internal error.
1191
 */
2 andreas 1192
bool TConfig::readConfig()
1193
{
35 andreas 1194
    ifstream fs;
2 andreas 1195
 
35 andreas 1196
    // First initialize the defaults
1197
    localSettings.ID = 0;
1198
    localSettings.port = 1397;
1199
    localSettings.ptype = "android";
1200
    localSettings.version = "1.0";
1201
    localSettings.longformat = false;
43 andreas 1202
    localSettings.profiling = false;
71 andreas 1203
    localSettings.systemSoundState = true;
1204
    localSettings.systemSound = "singleBeep.wav";
1205
    localSettings.systemSingleBeep = "singleBeep01.wav";
1206
    localSettings.systemDoubleBeep = "doubleBeep01.wav";
112 andreas 1207
    localSettings.ftpUser = "administrator";
1208
    localSettings.ftpPassword = "password";
115 andreas 1209
    localSettings.ftpSurface = "tpanel.tp4";
116 andreas 1210
    localSettings.sip_port = 5060;
43 andreas 1211
#ifdef __ANDROID__
1212
    localSettings.logLevel = SLOG_NONE;
59 andreas 1213
    localSettings.logLevelBits = HLOG_NONE;
43 andreas 1214
#else
1215
    localSettings.logLevel = SLOG_PROTOCOL;
1216
#endif
2 andreas 1217
 
35 andreas 1218
    // Now get the settings from file
1219
    try
1220
    {
1221
        fs.open(mCFile.c_str(), fstream::in);
1222
    }
1223
    catch (const fstream::failure e)
1224
    {
116 andreas 1225
        cerr << "TConfig::readConfig: Error on file " << mCFile << ": " << e.what() << endl;
35 andreas 1226
        TError::setError();
1227
        return false;
1228
    }
2 andreas 1229
 
35 andreas 1230
    for (string line; getline(fs, line);)
1231
    {
1232
        size_t pos;
2 andreas 1233
 
35 andreas 1234
        if ((pos = line.find("#")) != string::npos)
1235
        {
1236
            if (pos == 0)
1237
                line.clear();
1238
            else
1239
                line = line.substr(0, pos);
1240
        }
2 andreas 1241
 
35 andreas 1242
        if (line.empty() || line.find("=") == string::npos)
1243
            continue;
2 andreas 1244
 
35 andreas 1245
        vector<string> parts = split(line, "=", true);
2 andreas 1246
 
35 andreas 1247
        if (parts.size() == 2)
1248
        {
1249
            string left = parts[0];
1250
            string right = ltrim(parts[1]);
2 andreas 1251
 
35 andreas 1252
            if (caseCompare(left, "PORT") == 0 && !right.empty())
1253
                localSettings.port = atoi(right.c_str());
1254
            else if (caseCompare(left, "LOGFILE") == 0 && !right.empty())
1255
            {
1256
                localSettings.logFile = right;
23 andreas 1257
                TStreamError::setLogFileOnly(right);
35 andreas 1258
            }
1259
            else if (caseCompare(left, "LOGLEVEL") == 0 && !right.empty())
1260
            {
1261
                TStreamError::setLogLevel(right);
1262
                localSettings.logLevel = right;
59 andreas 1263
                localSettings.logLevelBits = logLevelStrToBits(right);
35 andreas 1264
            }
1265
            else if (caseCompare(left, "ProjectPath") == 0 && !right.empty())
43 andreas 1266
            {
35 andreas 1267
                localSettings.project = right;
43 andreas 1268
#ifdef __ANDROID__
1269
                TValidateFile vf;
1270
 
1271
                if (!vf.isValidFile(right))
1272
                {
1273
                    char *HOME = getenv("HOME");
1274
 
1275
                    if (HOME)
1276
                    {
1277
                        localSettings.project = HOME;
1278
                        localSettings.project += "/tpanel";
1279
                    }
1280
                }
1281
#endif
1282
            }
11 andreas 1283
            else if (caseCompare(left, "System") == 0 && !right.empty())
1284
                localSettings.system = atoi(right.c_str());
1285
            else if (caseCompare(left, "PanelType") == 0 && !right.empty())
35 andreas 1286
                localSettings.ptype = right;
1287
            else if (caseCompare(left, "Address") == 0 && !right.empty())
1288
                localSettings.server = right;
1289
            else if (caseCompare(left, "Firmware") == 0 && !right.empty())
1290
                localSettings.version = right;
1291
            else if (caseCompare(left, "LongFormat") == 0 && !right.empty())
71 andreas 1292
                localSettings.longformat = isTrue(right);
35 andreas 1293
            else if (caseCompare(left, "NoBanner") == 0 && !right.empty())
71 andreas 1294
                localSettings.noBanner = isTrue(right);
35 andreas 1295
            else if (caseCompare(left, "CertCheck") == 0 && !right.empty())
71 andreas 1296
                localSettings.certCheck = isTrue(right);
21 andreas 1297
            else if (caseCompare(left, "Channel") == 0 && !right.empty())
35 andreas 1298
            {
1299
                localSettings.ID = atoi(right.c_str());
2 andreas 1300
 
113 andreas 1301
                if (localSettings.ID < 10000 || localSettings.ID >= 29000)
35 andreas 1302
                {
116 andreas 1303
                    cerr << "TConfig::readConfig: Invalid port number " << right << endl;
35 andreas 1304
                    localSettings.ID = 0;
1305
                }
1306
            }
26 andreas 1307
            else if (caseCompare(left, "Scale") == 0 && !right.empty())
71 andreas 1308
                localSettings.scale = isTrue(right);
120 andreas 1309
            else if (caseCompare(left, "ToolbarForce") == 0 && !right.empty())
1310
                localSettings.tbforce = isTrue(right);
35 andreas 1311
            else if (caseCompare(left, "Profiling") == 0 && !right.empty())
71 andreas 1312
                localSettings.profiling = isTrue(right);
51 andreas 1313
            else if (caseCompare(left, "Password1") == 0 && !right.empty())
1314
                localSettings.password1 = right;
1315
            else if (caseCompare(left, "Password2") == 0 && !right.empty())
1316
                localSettings.password2 = right;
1317
            else if (caseCompare(left, "Password3") == 0 && !right.empty())
1318
                localSettings.password3 = right;
1319
            else if (caseCompare(left, "Password4") == 0 && !right.empty())
1320
                localSettings.password4 = right;
71 andreas 1321
            else if (caseCompare(left, "SystemSoundFile") == 0 && !right.empty())
1322
                localSettings.systemSound = right;
1323
            else if (caseCompare(left, "SystemSoundState") == 0 && !right.empty())
1324
                localSettings.systemSoundState = isTrue(right);
1325
            else if (caseCompare(left, "SystemSingleBeep") == 0 && !right.empty())
1326
                localSettings.systemSingleBeep = right;
1327
            else if (caseCompare(left, "SystemDoubleBeep") == 0 && !right.empty())
1328
                localSettings.systemDoubleBeep = right;
112 andreas 1329
            else if (caseCompare(left, "FTPuser") == 0 && !right.empty())       // FTP credentials
1330
                localSettings.ftpUser = right;
1331
            else if (caseCompare(left, "FTPpassword") == 0 && !right.empty())
1332
                localSettings.ftpPassword = right;
115 andreas 1333
            else if (caseCompare(left, "FTPsurface") == 0 && !right.empty())
1334
                localSettings.ftpSurface = right;
116 andreas 1335
            else if (caseCompare(left, "FTPpassive") == 0 && !right.empty())
1336
                localSettings.ftpPassive = isTrue(right);
115 andreas 1337
            else if (caseCompare(left, "FTPdownloadTime") == 0 && !right.empty())
1338
                localSettings.ftpLastDownload = atol(right.c_str());
104 andreas 1339
            else if (caseCompare(left, "SIP_PROXY") == 0 && !right.empty())     // SIP settings starting here
1340
                localSettings.sip_proxy = right;
1341
            else if (caseCompare(left, "SIP_PORT") == 0 && !right.empty())
1342
                localSettings.sip_port = atoi(right.c_str());
1343
            else if (caseCompare(left, "SIP_STUN") == 0 && !right.empty())
1344
                localSettings.sip_stun = right;
1345
            else if (caseCompare(left, "SIP_DOMAIN") == 0 && !right.empty())
1346
                localSettings.sip_domain = right;
1347
            else if (caseCompare(left, "SIP_USER") == 0 && !right.empty())
1348
                localSettings.sip_user = right;
1349
            else if (caseCompare(left, "SIP_PASSWORD") == 0 && !right.empty())
1350
                localSettings.sip_password = right;
1351
            else if (caseCompare(left, "SIP_ENABLED") == 0 && !right.empty())
1352
                localSettings.sip_enabled = isTrue(right);
26 andreas 1353
        }
35 andreas 1354
    }
2 andreas 1355
 
35 andreas 1356
    fs.close();
116 andreas 1357
    mInitialized = true;
1358
    TStreamError::setLogLevel(localSettings.logLevel);
1359
    TStreamError::setLogFile(localSettings.logFile);
2 andreas 1360
 
23 andreas 1361
    if (TStreamError::checkFilter(HLOG_DEBUG))
35 andreas 1362
    {
1363
        MSG_INFO("Selected Parameters:");
1364
        MSG_INFO("    Path to cfg.: " << localSettings.path);
1365
        MSG_INFO("    Name of cfg.: " << localSettings.name);
23 andreas 1366
#ifndef __ANDROID__
1367
        MSG_INFO("    Logfile:      " << localSettings.logFile);
1368
#endif
26 andreas 1369
        MSG_INFO("    LogLevel:     " << localSettings.logLevel);
35 andreas 1370
        MSG_INFO("    Long format:  " << (localSettings.longformat ? "YES" : "NO"));
1371
        MSG_INFO("    Project path: " << localSettings.project);
23 andreas 1372
#ifndef __ANDROID__
35 andreas 1373
        MSG_INFO("    Show banner:  " << (localSettings.noBanner ? "NO" : "YES"));
23 andreas 1374
#endif
35 andreas 1375
        MSG_INFO("    Controller:   " << localSettings.server);
1376
        MSG_INFO("    Port:         " << localSettings.port);
1377
        MSG_INFO("    Channel:      " << localSettings.ID);
1378
        MSG_INFO("    Panel type:   " << localSettings.ptype);
1379
        MSG_INFO("    Firmware ver. " << localSettings.version);
26 andreas 1380
        MSG_INFO("    Scaling:      " << (localSettings.scale ? "YES" : "NO"));
35 andreas 1381
        MSG_INFO("    Profiling:    " << (localSettings.profiling ? "YES" : "NO"));
71 andreas 1382
        MSG_INFO("    System Sound: " << localSettings.systemSound);
1383
        MSG_INFO("    Sound state:  " << (localSettings.systemSoundState ? "ACTIVATED" : "DEACTIVATED"));
1384
        MSG_INFO("    Single beep:  " << localSettings.systemSingleBeep);
1385
        MSG_INFO("    Double beep:  " << localSettings.systemDoubleBeep);
115 andreas 1386
        MSG_INFO("    FTP user:     " << localSettings.ftpUser);
1387
        MSG_INFO("    FTP password: " << localSettings.ftpPassword);
1388
        MSG_INFO("    FTP surface:  " << localSettings.ftpSurface);
116 andreas 1389
        MSG_INFO("    FTP passive:  " << (localSettings.ftpPassive ? "YES" : "NO"));
115 andreas 1390
        MSG_INFO("    FTP dl. time: " << localSettings.ftpLastDownload);
35 andreas 1391
    }
2 andreas 1392
 
35 andreas 1393
    return true;
2 andreas 1394
}
1395
 
21 andreas 1396
/**
1397
 * @brief TConfig::split splitts a string into parts.
1398
 *
1399
 * The method splitts a string into parts separated by \p seps. It puts the
1400
 * parts into a vector array.
1401
 *
1402
 * @param str           The string to split
1403
 * @param seps          The separator(s)
1404
 * @param trimEmpty     `true` = trum the parts.
1405
 *
1406
 * @return A vector array containing the parts of the string \p str.
1407
 */
2 andreas 1408
vector<string> TConfig::split(const string& str, const string& seps, const bool trimEmpty)
1409
{
116 andreas 1410
    DECL_TRACER("TConfig::split(const string& str, const string& seps, const bool trimEmpty)");
1411
 
2 andreas 1412
	size_t pos = 0, mark = 0;
1413
	vector<string> parts;
1414
 
1415
	for (auto it = str.begin(); it != str.end(); ++it)
1416
	{
1417
		for (auto sepIt = seps.begin(); sepIt != seps.end(); ++sepIt)
1418
		{
1419
			if (*it == *sepIt)
1420
			{
1421
				size_t len = pos - mark;
1422
				parts.push_back(str.substr(mark, len));
1423
				mark = pos + 1;
1424
				break;
1425
			}
1426
		}
1427
 
1428
		pos++;
1429
	}
1430
 
1431
	parts.push_back(str.substr(mark));
1432
 
1433
	if (trimEmpty)
1434
	{
1435
		vector<string> nparts;
1436
 
1437
		for (auto it = parts.begin(); it != parts.end(); ++it)
1438
		{
1439
			if (it->empty())
1440
				continue;
1441
 
1442
			nparts.push_back(*it);
1443
		}
1444
 
1445
		return nparts;
1446
	}
1447
 
1448
	return parts;
1449
}
1450
 
21 andreas 1451
/**
1452
 * @brief TConfig::caseCompare compares 2 strings
1453
 *
1454
 * This method compares 2 strings case insensitive. This means that it ignores
1455
 * the case of the letters. For example:
1456
 *
1457
 *     BLAME
1458
 *     blame
1459
 *     Blame
1460
 *
1461
 * are all the same and would return 0, which means _equal_.
1462
 *
1463
 * @param str1  1st string to compare
1464
 * @param str2  2nd string to compare
1465
 *
1466
 * @return 0 if the strings are equal\n
1467
 * less than 0 if the byte of \p str1 is bigger than the byte of \p str2\n
1468
 * grater than 0 if the byte of \p str1 is smaller than the byte of \p str2.
1469
 */
2 andreas 1470
int TConfig::caseCompare(const string& str1, const string& str2)
1471
{
116 andreas 1472
    DECL_TRACER("TConfig::caseCompare(const string& str1, const string& str2)");
1473
 
2 andreas 1474
	size_t i = 0;
1475
 
1476
	if (str1.length() != str2.length())
1477
		return ((str1.length() < str2.length()) ? -1 : 1);
1478
 
1479
	for (auto it = str1.begin(); it != str1.end(); ++it)
1480
	{
1481
		if (tolower(*it) != tolower(str2.at(i)))
1482
			return (int)(*it - str2.at(i));
1483
 
1484
		i++;
1485
	}
1486
 
1487
	return 0;
1488
}