Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
11 andreas 1
/*
101 andreas 2
 * Copyright (C) 2020 to 2022 by Andreas Theofilu <andreas@theosys.at>
11 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
 */
18
 
19
#include "tamxcommands.h"
20
#include "terror.h"
21
#include "tresources.h"
14 andreas 22
#include "tconfig.h"
78 andreas 23
#include "texpat++.h"
11 andreas 24
 
83 andreas 25
#include <string>
26
#include <vector>
27
 
11 andreas 28
using std::string;
29
using std::vector;
78 andreas 30
using namespace Expat;
11 andreas 31
 
32
typedef struct CMD_DEFINATIONS
33
{
34
    string cmd;
35
    bool hasChannels{false};
36
    bool hasPars{false};
14 andreas 37
    char separator{0};
11 andreas 38
}CMD_DEFINATIONS;
39
 
40
CMD_DEFINATIONS cmdDefinations[] = {
14 andreas 41
    { "@WLD", false, true, ',' },
42
    { "@AFP", false, true, ',' },
127 andreas 43
    { "^AFP", false, true, ',' },
14 andreas 44
    { "@GCE", false, true, ',' },
127 andreas 45
    { "^GCE", false, true, ',' },
14 andreas 46
    { "@APG", false, true, ';' },
47
    { "@CPG", false, true, ',' },
48
    { "@DPG", false, true, ';' },
49
    { "@PDR", false, true, ';' },
50
    { "@PHE", false, true, ';' },
51
    { "@PHP", false, true, ';' },
52
    { "@PHT", false, true, ';' },
53
    { "@PPA", false, true, ',' },
104 andreas 54
    { "^PPA", false, true, ',' },
14 andreas 55
    { "@PPF", false, true, ';' },
104 andreas 56
    { "^PPF", false, true, ';' },
14 andreas 57
    { "@PPG", false, true, ';' },
104 andreas 58
    { "^PPG", false, true, ';' },
14 andreas 59
    { "@PPK", false, true, ',' },
104 andreas 60
    { "^PPK", false, true, ',' },
14 andreas 61
    { "@PPM", false, true, ';' },
104 andreas 62
    { "^PPM", false, true, ';' },
14 andreas 63
    { "@PPN", false, true, ';' },
104 andreas 64
    { "^PPN", false, true, ';' },
14 andreas 65
    { "@PPT", false, true, ';' },
104 andreas 66
    { "^PPT", false, true, ';' },
14 andreas 67
    { "@PPX", false, false, '\0' },
104 andreas 68
    { "^PPX", false, false, '\0' },
14 andreas 69
    { "@PSE", false, true, ';' },
70
    { "@PSP", false, true, ';' },
71
    { "@PST", false, true, ';' },
72
    { "PAGE", false, true, ',' },
104 andreas 73
    { "^PGE", false, true, ',' },
14 andreas 74
    { "PPOF", false, true, ';' },
75
    { "PPOG", false, true, ';' },
76
    { "PPON", false, true, ';' },
77
    { "^ANI", true, true, ',' },
78
    { "^APF", true, true, ',' },
79
    { "^BAT", true, true, ',' },
80
    { "^BAU", true, true, ',' },
81
    { "^BCB", true, true, ',' },
82
    { "?BCB", true, true, ',' },
83
    { "^BCF", true, true, ',' },
84
    { "?BCF", true, true, ',' },
85
    { "^BCT", true, true, ',' },
86
    { "?BCT", true, true, ',' },
87
    { "^BDO", true, true, ',' },
88
    { "^BFB", true, true, ',' },
89
    { "^BIM", true, true, ',' },
90
    { "^BLN", true, true, ',' },
91
    { "^BMC", true, true, ',' },
92
    { "^BMF", true, true, ',' },
93
    { "^BMI", true, true, ',' },
94
    { "^BML", true, true, ',' },
95
    { "^BMP", true, true, ',' },
96
    { "?BMP", true, true, ',' },
97
    { "^BNC", true, true, ',' },
98
    { "^BNN", true, true, ',' },
99
    { "^BNT", true, true, ',' },
100
    { "^BOP", true, true, ',' },
101
    { "?BOP", true, true, ',' },
102
    { "^BOR", true, true, ',' },
103
    { "^BOS", true, true, ',' },
104
    { "^BPP", true, true, ',' },
105
    { "^BRD", true, true, ',' },
106
    { "?BRD", true, true, ',' },
107
    { "^BSF", true, true, ',' },
108
    { "^BSP", true, true, ',' },
109
    { "^BSM", true, false, ',' },
110
    { "^BSO", true, true, ',' },
111
    { "^BVL", true, true, ',' },
112
    { "^BVN", false, true, ',' },
113
    { "^BVP", true, true, ',' },
114
    { "^BVT", true, true, ',' },
115
    { "^BWW", true, true, ',' },
116
    { "?BWW", true, true, ',' },
117
    { "^CPF", true, false, ',' },
118
    { "^DLD", false, false, ',' },
119
    { "^DPF", true, true, ',' },
120
    { "^ENA", true, true, ',' },
121
    { "^FON", true, true, ',' },
122
    { "?FON", true, true, ',' },
123
    { "^GDI", true, true, ',' },
124
    { "^GIV", true, true, ',' },
125
    { "^GLH", true, true, ',' },
126
    { "^GLL", true, true, ',' },
127
    { "^GRD", true, true, ',' },
128
    { "^GRU", true, true, ',' },
129
    { "^GSC", true, true, ',' },
130
    { "^GSN", true, true, ',' },
131
    { "^ICO", true, true, ',' },
132
    { "?ICO", true, true, ',' },
133
    { "^IRM", false, true, ',' },
134
    { "^JSB", true, true, ',' },
135
    { "?JSB", true, true, ',' },
136
    { "^JSI", true, true, ',' },
137
    { "?JSI", true, true, ',' },
138
    { "^JST", true, true, ',' },
139
    { "?JST", true, true, ',' },
140
    { "^MBT", false, false, ',' },
141
    { "^MDC", false, false, ',' },
142
    { "^SHO", true, true, ',' },
143
    { "^TEC", true, true, ',' },
144
    { "?TEC", true, true, ',' },
145
    { "^TEF", true, true, ',' },
146
    { "?TEF", true, true, ',' },
147
    { "^TOP", false, true, ',' },
148
    { "^TXT", true, true, ',' },
149
    { "?TXT", true, true, ',' },
150
    { "^UNI", true, true, ',' },
104 andreas 151
    { "^UTF", true, true, ',' },
14 andreas 152
    { "^LPC", false, true, ',' },
153
    { "^LPR", false, true, ',' },
154
    { "^LPS", false, true, ',' },
155
    { "ABEEP", false, false, ',' },
156
    { "ADBEEP", false, false, ',' },
157
    { "@AKB", false, true, ';' },
158
    { "AKEYB", false, true, ',' },
159
    { "AKEYP", false, true, ',' },
160
    { "AKEYR", false, true, ',' },
161
    { "@AKP", false, true, ';' },
162
    { "@AKR", false, false, ',' },
163
    { "BEEP", false, false, ',' },
104 andreas 164
    { "^ABP", false, false, ',' },
14 andreas 165
    { "BRIT", false, true, ',' },
166
    { "@BRT", false, true, ',' },
167
    { "DBEEP", false, false, ',' },
104 andreas 168
    { "^ADP", false, false, ',' },
14 andreas 169
    { "@EKP", false, true, ';' },
170
    { "PKEYP", false, true, ',' },
63 andreas 171
    { "@PKB", false, true, ';' },
104 andreas 172
    { "^PKB", false, true, ';' },
14 andreas 173
    { "@PKP", false, true, ';' },
104 andreas 174
    { "^PKP", false, true, ';' },
14 andreas 175
    { "SETUP", false, false, ',' },
104 andreas 176
    { "^STP", false, false, ',' },
14 andreas 177
    { "SHUTDOWN", false, false, ',' },
178
    { "SLEEP", false, false, ',' },
179
    { "@SOU", false, true, ',' },
104 andreas 180
    { "^SOU", false, true, ',' },
14 andreas 181
    { "@TKP", false, true, ';' },
104 andreas 182
    { "^TKP", false, true, ';' },
14 andreas 183
    { "TPAGEON", false, false, ',' },
184
    { "TPAGEOFF", false, false, ',' },
185
    { "@VKB", false, false, ',' },
104 andreas 186
    { "^VKB", false, false, ',' },
14 andreas 187
    { "WAKE", false, false, ',' },
188
    { "^CAL", false, false, ',' },
189
    { "^KPS", false, true, ',' },
190
    { "^VKS", false, true, ',' },
127 andreas 191
    { "^WCN?", false, true, ',' },
14 andreas 192
    { "@PWD", false, true, ',' },
193
    { "^PWD", false, true, ',' },
194
    { "^BBR", true, true, ',' },
195
    { "^RAF", false, true, ',' },
196
    { "^RFR", false, true, ',' },
197
    { "^RMF", false, true, ',' },
198
    { "^RSR", false, true, ',' },
199
    { "^MODEL?", false, false, ',' },
127 andreas 200
    { "^MOD", false, false, ',' },
201
    { "^VER?", false, false, ',' },
14 andreas 202
    { "^ICS", false, true, ',' },
203
    { "^ICE", false, false, ',' },
204
    { "^ICM", false, true, ',' },
205
    { "^PHN", false, true, ',' },
206
    { "?PHN", false, true, ',' },
127 andreas 207
    { "GET ", false, false, ',' },
208
    { "SET ", false, false, ',' },
14 andreas 209
    { "LEVON", false, false, ',' },
210
    { "RXON", false, false, ',' },
211
    { "ON", false, true, ',' },
212
    { "OFF", false, true, ',' },
15 andreas 213
    { "LEVEL", false, true, ',' },
214
    { "BLINK", false, true, ',' },
23 andreas 215
    { "#FTR", false, true, ':' },
134 andreas 216
    { "TPCCMD", false, true, ',' },
217
    { "TPCACC", false, true, ',' },
153 andreas 218
    { "TPCSIP", false, true, ',' },
14 andreas 219
    { "", false, false, '\0' }
11 andreas 220
};
221
 
222
CMD_DEFINATIONS& findCmdDefines(const string& cmd)
223
{
224
    DECL_TRACER("findCmdDefines(const string& cmd)");
225
 
226
    int i = 0;
101 andreas 227
    string uCmd = cmd;
228
    uCmd = toUpper(uCmd);
11 andreas 229
 
230
    while (cmdDefinations[i].cmd.length() > 0)
231
    {
101 andreas 232
        if (cmdDefinations[i].cmd.compare(uCmd) == 0)
11 andreas 233
            return cmdDefinations[i];
234
 
235
        i++;
236
    }
237
 
238
    return cmdDefinations[i];
239
}
240
 
241
TAmxCommands::TAmxCommands()
242
{
243
    DECL_TRACER("TAmxCommands::TAmxCommands()");
244
}
245
 
246
TAmxCommands::~TAmxCommands()
247
{
248
    DECL_TRACER("TAmxCommands::~TAmxCommands()");
249
}
250
 
14 andreas 251
bool TAmxCommands::readMap()
252
{
253
    DECL_TRACER("TAmxCommands::readMap()");
254
 
88 andreas 255
    string path = makeFileName(TConfig::getProjectPath(), "map.xma");
14 andreas 256
    vector<string> elements = { "cm", "am", "lm", "bm", "sm", "strm", "pm" };
257
 
88 andreas 258
    if (!isValidFile())
259
    {
260
        MSG_ERROR("File \"" << path << "\" is not a regular readable file!");
261
        return false;
262
    }
14 andreas 263
 
78 andreas 264
    TExpat xml(path);
265
    xml.setEncoding(ENC_CP1250);
14 andreas 266
 
78 andreas 267
    if (!xml.parse())
14 andreas 268
        return false;
269
 
78 andreas 270
    int depth = 0;
271
    size_t index = 0;
14 andreas 272
    vector<string>::iterator mapIter;
78 andreas 273
    size_t oldIndex = 0;
14 andreas 274
 
88 andreas 275
    if (elements.size() == 0)
276
        return false;
277
 
118 andreas 278
    for (mapIter = elements.begin(); mapIter != elements.end(); ++mapIter)
14 andreas 279
    {
78 andreas 280
        if ((index = xml.getElementIndex(*mapIter, &depth)) == TExpat::npos)
14 andreas 281
        {
23 andreas 282
            MSG_WARNING("Element \"" << *mapIter << "\" was not found!");
283
            continue;
14 andreas 284
        }
285
 
286
        MAP_T map;
287
        MAP_BM_T mapBm;
288
        MAP_PM_T mapPm;
78 andreas 289
        string name, content;
14 andreas 290
 
78 andreas 291
        while ((index = xml.getNextElementFromIndex(index, &name, nullptr, nullptr)) != TExpat::npos)
14 andreas 292
        {
78 andreas 293
            string el = name;
14 andreas 294
 
295
            if (el.compare("me") == 0)
296
            {
78 andreas 297
                while ((index = xml.getNextElementFromIndex(index, &name, &content, nullptr)) != TExpat::npos)
14 andreas 298
                {
78 andreas 299
                    string e = name;
14 andreas 300
 
301
                    if (mapIter->compare("cm") == 0 || mapIter->compare("am") == 0 ||
302
                        mapIter->compare("lm") == 0 || mapIter->compare("strm") == 0)
303
                    {
304
                        if (e.compare("p") == 0)
78 andreas 305
                            map.p = xml.convertElementToInt(content);
14 andreas 306
                        else if (e.compare("c") == 0)
78 andreas 307
                            map.c = xml.convertElementToInt(content);
14 andreas 308
                        else if (e.compare("ax") == 0)
78 andreas 309
                            map.ax = xml.convertElementToInt(content);
14 andreas 310
                        else if (e.compare("pg") == 0)
78 andreas 311
                            map.pg = xml.convertElementToInt(content);
14 andreas 312
                        else if (e.compare("bt") == 0)
78 andreas 313
                            map.bt = xml.convertElementToInt(content);
14 andreas 314
                        else if (e.compare("pn") == 0)
78 andreas 315
                            map.pn = content;
14 andreas 316
                        else if (e.compare("bn") == 0)
78 andreas 317
                            map.bn = content;
14 andreas 318
                    }
319
                    else if (mapIter->compare("bm") == 0)
320
                    {
78 andreas 321
                        while ((index = xml.getNextElementFromIndex(index, &name, &content, nullptr)) != TExpat::npos)
14 andreas 322
                        {
78 andreas 323
                            string im = name;
14 andreas 324
 
325
                            if (im.compare("i") == 0)
78 andreas 326
                                mapBm.i = content;
14 andreas 327
                            else if (im.compare("id") == 0)
78 andreas 328
                                mapBm.id = xml.convertElementToInt(content);
14 andreas 329
                            else if (im.compare("rt") == 0)
78 andreas 330
                                mapBm.rt = xml.convertElementToInt(content);
14 andreas 331
                            else if (im.compare("pg") == 0)
78 andreas 332
                                mapBm.pg = xml.convertElementToInt(content);
14 andreas 333
                            else if (im.compare("bt") == 0)
78 andreas 334
                                mapBm.bt = xml.convertElementToInt(content);
14 andreas 335
                            else if (im.compare("st") == 0)
78 andreas 336
                                mapBm.st = xml.convertElementToInt(content);
14 andreas 337
                            else if (im.compare("sl") == 0)
78 andreas 338
                                mapBm.sl = xml.convertElementToInt(content);
14 andreas 339
                            else if (im.compare("pn") == 0)
78 andreas 340
                                mapBm.pn = content;
14 andreas 341
                            else if (im.compare("bn") == 0)
78 andreas 342
                                mapBm.bn = content;
14 andreas 343
 
78 andreas 344
                            oldIndex = index;
14 andreas 345
                        }
346
 
347
                        mMap.map_bm.push_back(mapBm);
78 andreas 348
 
349
                        if (index == TExpat::npos)
350
                            index = oldIndex + 1;
14 andreas 351
                    }
352
                    else if (mapIter->compare("sm") == 0)
353
                    {
354
                        if (e.compare("i") == 0)
78 andreas 355
                            mMap.map_sm.push_back(content);
14 andreas 356
                    }
357
                    else if (mapIter->compare("pm") == 0)
358
                    {
359
                        if (e.compare("a") == 0)
78 andreas 360
                            mapPm.a = xml.convertElementToInt(content);
14 andreas 361
                        else if (e.compare("t") == 0)
78 andreas 362
                            mapPm.t = content;
14 andreas 363
                        else if (e.compare("pg") == 0)
78 andreas 364
                            mapPm.pg = xml.convertElementToInt(content);
14 andreas 365
                        else if (e.compare("bt") == 0)
78 andreas 366
                            mapPm.bt = xml.convertElementToInt(content);
14 andreas 367
                        else if (e.compare("pn") == 0)
78 andreas 368
                            mapPm.pn = content;
14 andreas 369
                        else if (e.compare("bn") == 0)
78 andreas 370
                            mapPm.bn = content;
14 andreas 371
                    }
372
 
78 andreas 373
                    oldIndex = index;
14 andreas 374
                }
375
 
376
                if (mapIter->compare("cm") == 0)
377
                    mMap.map_cm.push_back(map);
378
                else if (mapIter->compare("am") == 0)
379
                    mMap.map_am.push_back(map);
380
                else if (mapIter->compare("lm") == 0)
381
                    mMap.map_lm.push_back(map);
382
                else if (mapIter->compare("strm") == 0)
383
                    mMap.map_strm.push_back(map);
384
                else if (mapIter->compare("pm") == 0)
385
                    mMap.map_pm.push_back(mapPm);
78 andreas 386
 
387
                if (index == TExpat::npos)
388
                    index = oldIndex + 1;
14 andreas 389
            }
390
 
78 andreas 391
            oldIndex = index;
14 andreas 392
        }
393
    }
394
 
395
    return true;
396
}
397
 
398
vector<string> TAmxCommands::getFields(string& msg, char sep)
399
{
400
    DECL_TRACER("TAmxCommands::getFields(string& msg, char sep)");
401
 
402
    vector<string> flds;
403
    bool bStr = false;
404
    string part;
405
 
16 andreas 406
    for (size_t i = 0; i < msg.length(); i++)
14 andreas 407
    {
16 andreas 408
        if (msg.at(i) == sep && !bStr)
14 andreas 409
        {
410
            flds.push_back(part);
411
            part.clear();
412
            continue;
413
        }
16 andreas 414
        else if (msg.at(i) == '\'' && !bStr)
14 andreas 415
            bStr = true;
16 andreas 416
        else if (msg.at(i) == '\'' && bStr)
14 andreas 417
            bStr = false;
418
        else
16 andreas 419
            part.append(msg.substr(i, 1));
14 andreas 420
    }
421
 
422
    if (!part.empty())
423
        flds.push_back(part);
424
 
83 andreas 425
    if (flds.size() > 0 && TStreamError::checkFilter(HLOG_DEBUG))
14 andreas 426
    {
427
        MSG_DEBUG("Found fields:");
428
        vector<string>::iterator iter;
429
        int i = 1;
430
 
118 andreas 431
        for (iter = flds.begin(); iter != flds.end(); ++iter)
14 andreas 432
        {
433
            MSG_DEBUG("    " << i << ": " << *iter);
434
            i++;
435
        }
436
    }
437
 
438
    return flds;
439
}
440
 
19 andreas 441
vector<MAP_T> TAmxCommands::findButtons(int port, vector<int>& channels, MAP_TYPE mt)
14 andreas 442
{
19 andreas 443
    DECL_TRACER("TAmxCommands::findButtons(int port, vector<int>& channels, MAP_TYPE mt)");
14 andreas 444
 
445
    vector<MAP_T> map;
446
    vector<int>::iterator iter;
447
 
19 andreas 448
    if (channels.empty())
449
    {
450
        MSG_WARNING("Got empty channel list!");
451
        return map;
452
    }
453
 
454
    vector<MAP_T> localMap;
455
 
456
    switch (mt)
457
    {
458
        case TYPE_AM:   localMap = mMap.map_am; break;
459
        case TYPE_CM:   localMap = mMap.map_cm; break;
460
        case TYPE_LM:   localMap = mMap.map_lm; break;
461
    }
462
 
463
    if (localMap.empty())
464
    {
465
        MSG_WARNING("The internal list of elements is empty!")
466
        return map;
467
    }
468
 
118 andreas 469
    for (iter = channels.begin(); iter != channels.end(); ++iter)
14 andreas 470
    {
471
        vector<MAP_T>::iterator mapIter;
472
 
118 andreas 473
        for (mapIter = localMap.begin(); mapIter != localMap.end(); ++mapIter)
14 andreas 474
        {
475
            if (mapIter->p == port && mapIter->c == *iter)
476
                map.push_back(*mapIter);
477
        }
478
    }
479
 
480
    MSG_DEBUG("Found " << map.size() << " buttons.");
481
    return map;
482
}
483
 
165 andreas 484
string TAmxCommands::findImage(int bt, int page, int instance)
485
{
486
    DECL_TRACER("TAmxCommands::findImage(int bt, int page, int instance)");
487
 
488
    vector<MAP_BM_T> mapBm = mMap.map_bm;
489
    vector<MAP_BM_T>::iterator iter;
490
 
491
    if (mapBm.empty())
492
        return string();
493
 
494
    for (iter = mapBm.begin(); iter != mapBm.end(); ++iter)
495
    {
496
        if (iter->bt == bt && iter->pg == page && !iter->i.empty())
497
        {
498
            if (instance >= 0 && iter->st == (instance + 1))
499
                return iter->i;
500
            else if (instance < 0)
501
                return iter->i;
502
        }
503
    }
504
 
505
    return string();
506
}
507
 
508
string TAmxCommands::findImage(const string& name)
509
{
510
    DECL_TRACER("TAmxCommands::findImage(const string& name)");
511
 
512
    vector<MAP_BM_T> mapBm = mMap.map_bm;
513
    vector<MAP_BM_T>::iterator iter;
514
 
515
    if (mapBm.empty() || name.empty())
516
        return string();
517
 
518
    size_t cnt = 0;
519
 
520
    for (iter = mapBm.begin(); iter != mapBm.end(); ++iter)
521
    {
522
        if (!iter->i.empty() && iter->i.find(name) != string::npos)
523
        {
524
            size_t pos = iter->i.find_last_of(".");
525
 
526
            if (pos != string::npos)
527
            {
528
                string left = iter->i.substr(0, pos);
529
MSG_DEBUG("Found candidate: " << iter->i << " (" << left << ")");
530
                if (left == name)
531
                    return iter->i;
532
            }
533
        }
534
 
535
        cnt++;
536
    }
537
 
538
    MSG_WARNING("No image with name " << name << " in table found!");
539
    MSG_DEBUG("Searched " << cnt << " entries for image " << name);
540
    return string();
541
}
542
 
97 andreas 543
vector<MAP_T> TAmxCommands::findButtonByName(const string& name)
544
{
545
    DECL_TRACER("TAmxCommands::findButtonByName(const string& name)");
546
 
547
    vector<MAP_T> map;
548
 
549
    if (mMap.map_cm.empty())
550
    {
551
        MSG_WARNING("The internal list of elements is empty!")
552
        return map;
553
    }
554
 
555
    vector<MAP_T>::iterator mapIter;
556
 
118 andreas 557
    for (mapIter = mMap.map_cm.begin(); mapIter != mMap.map_cm.end(); ++mapIter)
97 andreas 558
    {
559
        if (mapIter->bn == name)
560
            map.push_back(*mapIter);
561
    }
562
 
563
    MSG_DEBUG("Found " << map.size() << " buttons.");
564
    return map;
565
}
566
 
15 andreas 567
vector<MAP_T> TAmxCommands::findBargraphs(int port, vector<int>& channels)
568
{
569
    DECL_TRACER("TAmxCommands::findBargraphs(int port, vector<int>& channels)");
570
 
571
    vector<MAP_T> map;
572
    vector<int>::iterator iter;
573
 
83 andreas 574
    if (channels.size() == 0)
575
        return map;
576
 
118 andreas 577
    for (iter = channels.begin(); iter != channels.end(); ++iter)
15 andreas 578
    {
579
        vector<MAP_T>::iterator mapIter;
580
 
83 andreas 581
        if (mMap.map_lm.size() > 0)
15 andreas 582
        {
118 andreas 583
            for (mapIter = mMap.map_lm.begin(); mapIter != mMap.map_lm.end(); ++mapIter)
83 andreas 584
            {
585
                if (mapIter->p == port && mapIter->c == *iter)
586
                    map.push_back(*mapIter);
587
            }
15 andreas 588
        }
589
    }
590
 
591
    MSG_DEBUG("Found " << map.size() << " buttons.");
592
    return map;
593
}
594
 
107 andreas 595
vector<string> TAmxCommands::findSounds()
596
{
597
    DECL_TRACER("TAmxCommands::findSounds()");
598
 
599
    return mMap.map_sm;
600
}
601
 
118 andreas 602
bool TAmxCommands::soundExist(const string& sname)
107 andreas 603
{
604
    DECL_TRACER("TAmxCommands::soundExist(const string sname)");
605
 
606
    if (mMap.map_sm.size() == 0)
607
        return false;
608
 
609
    vector<string>::iterator iter;
610
 
611
    for (iter = mMap.map_sm.begin(); iter != mMap.map_sm.end(); ++iter)
612
    {
613
        if (iter->compare(sname) == 0)
614
            return true;
615
    }
616
 
617
    return false;
618
}
619
 
11 andreas 620
bool TAmxCommands::parseCommand(int device, int port, const string& cmd)
621
{
622
    DECL_TRACER("TAmxCommands::parseCommand(int device, int port, const string& cmd)");
65 andreas 623
/*
60 andreas 624
    if (device != TConfig::getChannel())    // This happens on a filetransfer only!
14 andreas 625
    {
626
        MSG_WARNING("Command is for device " << device << ", but this device is " << TConfig::getChannel());
627
    }
65 andreas 628
*/
11 andreas 629
    vector<CMD_TABLE>::iterator iter;
16 andreas 630
    size_t pos = cmd.find_first_of("-");
127 andreas 631
    int system = TConfig::getSystem();
632
    string scmd = getCommand(cmd);
11 andreas 633
 
127 andreas 634
    MSG_TRACE("Parsing for device <" << device << ":" << port << ":" << system << "> the command: " << scmd);
13 andreas 635
 
11 andreas 636
    if (pos != string::npos)    // Command with parameters
637
    {
638
        string rest = cmd.substr(pos + 1);
639
 
118 andreas 640
        for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 641
        {
13 andreas 642
            iter->channels.clear();
643
            iter->pars.clear();
644
 
153 andreas 645
            if (iter->cmd.compare(scmd) == 0 && iter->command)
11 andreas 646
            {
153 andreas 647
                CMD_DEFINATIONS cdef = findCmdDefines(scmd);
11 andreas 648
 
649
                if (cdef.cmd.empty())
650
                {
153 andreas 651
                    MSG_WARNING("Command \"" << scmd << "\" not found in command table! Ignoring it.");
11 andreas 652
                    continue;
653
                }
654
 
655
                if (cdef.hasChannels || cdef.hasPars)
656
                {
14 andreas 657
                    vector<string> parts = getFields(rest, cdef.separator);
11 andreas 658
 
659
                    if (cdef.hasChannels)
13 andreas 660
                        extractChannels(parts[0], &iter->channels);
11 andreas 661
 
662
                    if (cdef.hasPars)
663
                    {
13 andreas 664
                        MSG_DEBUG("Command may have parameters. Found " << parts.size() << " parameters.");
11 andreas 665
 
13 andreas 666
                        if (parts.size() > 0)
11 andreas 667
                        {
13 andreas 668
                            vector<string>::iterator piter;
669
                            int cnt = 0;
670
 
118 andreas 671
                            for (piter = parts.begin(); piter != parts.end(); ++piter)
11 andreas 672
                            {
13 andreas 673
                                if (cdef.hasChannels && !cnt)
674
                                {
675
                                    cnt++;
676
                                    continue;
677
                                }
678
 
679
                                iter->pars.push_back(*piter);
11 andreas 680
                                cnt++;
681
                            }
682
                        }
13 andreas 683
                        else
684
                            iter->pars.push_back(rest);
11 andreas 685
                    }
686
                }
687
 
688
                iter->command(port, iter->channels, iter->pars);
689
                return true;
690
            }
691
        }
692
    }
693
    else        // Command without parameter
694
    {
118 andreas 695
        for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 696
        {
153 andreas 697
            if (iter->cmd.compare(scmd) == 0 && iter->command)
11 andreas 698
            {
699
                iter->command(port, iter->channels, iter->pars);
700
                return true;
701
            }
702
        }
703
    }
704
 
705
    MSG_WARNING("Command \"" << cmd << "\" currently not supported!");
706
    return false;
707
}
708
 
709
bool TAmxCommands::extractChannels(const string& schan, vector<int>* ch)
710
{
711
    DECL_TRACER("TAmxCommands::extractChannels(const string& schan, vector<int>* ch)");
712
 
713
    if (!ch || schan.empty())
714
        return false;
715
 
16 andreas 716
    if (schan.find("&") == string::npos && schan.find(".") == string::npos)
11 andreas 717
    {
718
        int c = atoi(schan.c_str());
719
        ch->push_back(c);
720
        return true;
721
    }
722
 
723
    if (schan.find("&") != string::npos)
724
    {
725
        vector<string> parts = StrSplit(schan, "&");
726
        vector<string>::iterator iter;
727
 
83 andreas 728
        if (parts.size() > 0)
11 andreas 729
        {
118 andreas 730
            for (iter = parts.begin(); iter != parts.end(); ++iter)
11 andreas 731
            {
83 andreas 732
                if (iter->find(".") != string::npos)
733
                {
734
                    vector<string> p2 = StrSplit(*iter, ".");
11 andreas 735
 
83 andreas 736
                    if (p2.size() >= 2)
737
                    {
738
                        for (int i = atoi(p2[0].c_str()); i <= atoi(p2[1].c_str()); i++)
739
                            ch->push_back(i);
740
                    }
741
                    else if (p2.size() > 0)
742
                        ch->push_back(atoi(p2[0].c_str()));
38 andreas 743
                }
83 andreas 744
                else
745
                    ch->push_back(atoi(iter->c_str()));
11 andreas 746
            }
747
        }
748
    }
749
    else
750
    {
751
        vector<string> parts = StrSplit(schan, ".");
752
 
38 andreas 753
        if (parts.size() >= 2)
754
        {
60 andreas 755
            for (int i = atoi(parts[0].c_str()); i <= atoi(parts[1].c_str()); i++)
38 andreas 756
                ch->push_back(i);
757
        }
758
        else if (parts.size() > 0)
759
            ch->push_back(atoi(parts[0].c_str()));
11 andreas 760
    }
761
 
762
    return true;
763
}
764
 
765
void TAmxCommands::registerCommand(std::function<void (int port, vector<int>& channels, vector<string>& pars)> command, const string& name)
766
{
767
    DECL_TRACER("TAmxCommands::registerCommand(std::function<void (vector<int>& channels, vector<string>& pars)> command, const string& name)");
768
 
769
    vector<CMD_TABLE>::iterator iter;
770
 
118 andreas 771
    for (iter = mCmdTable.begin(); iter != mCmdTable.end(); ++iter)
11 andreas 772
    {
773
        if (iter->cmd.compare(name) == 0)
774
        {
775
            iter->command = command;
776
            iter->channels.clear();
777
            iter->pars.clear();
778
            return;
779
        }
780
    }
781
 
782
    CMD_TABLE ctbl;
783
    ctbl.cmd = name;
784
    ctbl.command = command;
785
    mCmdTable.push_back(ctbl);
786
}