• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nasa / trick / 4357077355

pending completion
4357077355

push

github

GitHub
Fix SIM_job_class_order (#1470)

12387 of 21399 relevant lines covered (57.89%)

916206.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.46
/trick_source/sim_services/VariableServer/VariableServerThread_commands.cpp
1

2
#include <string.h>
3
#include <iostream>
4
#include <sstream>
5
#include <stdlib.h>
6
#include <udunits2.h>
7
#include "trick/VariableServer.hh"
8
#include "trick/variable_server_message_types.h"
9
#include "trick/memorymanager_c_intf.h"
10
#include "trick/tc_proto.h"
11
#include "trick/exec_proto.h"
12
#include "trick/command_line_protos.h"
13
#include "trick/message_proto.h"
14
#include "trick/message_type.h"
15
#include "trick/TrickConstant.hh"
16
#include "trick/sie_c_intf.h"
17
#include "trick/UdUnits.hh"
18
#include "trick/map_trick_units_to_udunits.hh"
19

20
int Trick::VariableServerThread::bad_ref_int = 0 ;
21
int Trick::VariableServerThread::do_not_resolve_bad_ref_int = 0 ;
22

23
REF2* Trick::VariableServerThread::make_time_ref() {
6✔
24
    REF2* new_ref;
25
    new_ref = (REF2*)calloc(1, sizeof(REF2));
6✔
26
    new_ref->reference = strdup("time") ;
6✔
27
    new_ref->units = strdup("s") ;
6✔
28
    new_ref->address = (char *)&time ;
6✔
29
    new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
6✔
30
    new_ref->attr->type = TRICK_DOUBLE ;
6✔
31
    new_ref->attr->units = strdup("s") ;
6✔
32
    new_ref->attr->size = sizeof(double) ;
6✔
33
    return new_ref;
6✔
34
}
35

36
REF2* Trick::VariableServerThread::make_error_ref(std::string in_name) {
1✔
37
    REF2* new_ref;
38
    new_ref = (REF2*)calloc(1, sizeof(REF2));
1✔
39
    new_ref->reference = strdup(in_name.c_str()) ;
1✔
40
    new_ref->units = NULL ;
1✔
41
    new_ref->address = (char *)&bad_ref_int ;
1✔
42
    new_ref->attr = (ATTRIBUTES*)calloc(1, sizeof(ATTRIBUTES)) ;
1✔
43
    new_ref->attr->type = TRICK_NUMBER_OF_TYPES ;
1✔
44
    new_ref->attr->units = (char *)"--" ;
1✔
45
    new_ref->attr->size = sizeof(int) ;
1✔
46
    return new_ref;
1✔
47
}
48

49
Trick::VariableReference* Trick::VariableServerThread::create_var_reference(std::string in_name) {
104✔
50
    REF2 * new_ref ;
51

52
    // Time var is treated specially
53
    if ( in_name.compare("time") == 0 ) {
104✔
54
        new_ref = make_time_ref() ;
6✔
55
    } else {
56
        // otherwise ref_attributes takes care of the hard part
57
        new_ref = ref_attributes(in_name.c_str()) ;
98✔
58
    }
59

60
    // Check error cases
61
    if ( new_ref == NULL ) {
104✔
62
        message_publish(MSG_ERROR, "Variable Server could not find variable %s.\n", in_name.c_str());
1✔
63
        new_ref = make_error_ref(in_name);
1✔
64
    } else if ( new_ref->attr ) {
103✔
65
        if ( new_ref->attr->type == TRICK_STRUCTURED ) {
103✔
66
            message_publish(MSG_ERROR, "Variable Server: var_add cant add \"%s\" because its a composite variable.\n", in_name.c_str());
×
67
            // Replace the REF2 object we got from ref_attributes with an error-ref.
68
            free(new_ref);
×
69
            new_ref = make_error_ref(in_name);
×
70
            // set the address of the data to the do_not_resolve address.  We won't retry resolving the name
71
            new_ref->address = (char *)&do_not_resolve_bad_ref_int ;
×
72
        } else if ( new_ref->attr->type == TRICK_STL ) {
103✔
73
            message_publish(MSG_ERROR, "Variable Server: var_add cant add \"%s\" because its an STL variable.\n", in_name.c_str());
×
74
            // Replace the REF2 object we got from ref_attributes with an error-ref.
75
            free(new_ref);
×
76
            new_ref = make_error_ref(in_name);
×
77
            // set the address of the data to the do_not_resolve address.  We won't retry resolving the name
78
            new_ref->address = (char *)&do_not_resolve_bad_ref_int ;
×
79
        }
80
    } else {
81
        message_publish(MSG_ERROR, "Variable Server: BAD MOJO - Missing ATTRIBUTES.");
×
82
        new_ref = make_error_ref(in_name);
×
83
    }
84

85
    // Actually constructs the variable reference in the success case
86
    return new VariableReference(new_ref) ;
104✔
87
}
88

89
int Trick::VariableServerThread::var_add(std::string in_name) {
55✔
90
    VariableReference * new_var = create_var_reference(in_name);
55✔
91
    vars.push_back(new_var) ;
55✔
92

93
    return(0) ;
55✔
94
}
95

96
int Trick::VariableServerThread::var_add(std::string var_name, std::string units_name) {
3✔
97
    var_add(var_name) ;
3✔
98
    var_units(var_name, units_name) ;
3✔
99
    return(0) ;
3✔
100
}
101

102
// Helper function for var_send_once
103
std::vector<std::string> split (const std::string& str, const char delim) {
48✔
104
    std::stringstream ss(str);
96✔
105
    std::string s;
96✔
106
    std::vector<std::string> ret;
48✔
107
    while (std::getline(ss, s, delim)) {
100✔
108
        ret.push_back(s);
52✔
109
    }
110
    return ret;
96✔
111
}
112

113
int Trick::VariableServerThread::var_send_once(std::string in_name, int num_vars) {
48✔
114
    std::vector<std::string> var_names = split(in_name, ',');
96✔
115

116
    if (var_names.size() != num_vars) {
48✔
117
        message_publish(MSG_ERROR, "Number of variables sent to var_send_once (%d) does not match num_vars (%d).\n", var_names.size(), num_vars);
1✔
118
        return -1;
1✔
119
    }
120

121
    std::vector<VariableReference *> given_vars;
47✔
122
    for (auto& varName : var_names) {
96✔
123
        given_vars.push_back(create_var_reference(varName));
49✔
124
    }
125
    copy_sim_data(given_vars, false);
47✔
126
    write_data(given_vars);
47✔
127

128
    return(0) ;
47✔
129
}
130

131

132
int Trick::VariableServerThread::var_remove(std::string in_name) {
4✔
133

134
    unsigned int ii ;
135
    for ( ii = 0 ; ii < vars.size() ; ii++ ) {
8✔
136
        std::string var_name = vars[ii]->ref->reference;
8✔
137
        if ( ! var_name.compare(in_name) ) {
8✔
138
            delete vars[ii];
4✔
139
            vars.erase(vars.begin() + ii) ;
4✔
140
            break ;
4✔
141
        }
142
    }
143

144
    return(0) ;
4✔
145

146
}
147

148
int Trick::VariableServerThread::var_units(std::string var_name, std::string units_name) {
5✔
149
    for ( VariableReference* variable : vars ) {
13✔
150
        if ( std::string(variable->ref->reference).compare(var_name) ) {
9✔
151
            continue;
4✔
152
        }
153

154
        if (!units_name.compare("xx")) {
5✔
155
            units_name = variable->ref->attr->units;
×
156
        }
157

158
        auto publish = [](MESSAGE_TYPE type, const std::string& message) {
1✔
159
            std::ostringstream oss;
1✔
160
            oss << "Variable Server: " << message << std::endl;
1✔
161
            message_publish(type, oss.str().c_str());
1✔
162
        };
1✔
163
        /* if unitless ('--') then do not convert to udunits*/
164
        if(units_name.compare("--")){
5✔
165
            std::string new_units = map_trick_units_to_udunits(units_name) ;
5✔
166
            if ( units_name.compare(new_units) ) {
5✔
167
                std::ostringstream oss;
×
168
                oss << "[" << var_name << "] old-style units converted from ["
169
                    << units_name << "] to [" << new_units << "]";
×
170
                publish(MSG_WARNING, oss.str());
×
171
            }
172

173
            auto publishError = [&](const std::string& units) {
×
174
                std::ostringstream oss;
×
175
                oss << "units error for [" << var_name << "] [" << units << "]";
×
176
                publish(MSG_ERROR, oss.str());
×
177
            };
×
178

179
            ut_unit * from = ut_parse(Trick::UdUnits::get_u_system(), variable->ref->attr->units, UT_ASCII) ;
5✔
180
            if ( !from ) {
5✔
181
                publishError(variable->ref->attr->units);
×
182
                ut_free(from) ;
×
183
                return -1 ;
×
184
            }
185

186
            ut_unit * to = ut_parse(Trick::UdUnits::get_u_system(), new_units.c_str(), UT_ASCII) ;
5✔
187
            if ( !to ) {
5✔
188
                publishError(new_units);
×
189
                ut_free(from) ;
×
190
                ut_free(to) ;
×
191
                return -1 ;
×
192
            }
193

194
            cv_converter * conversion_factor = ut_get_converter(from, to) ;
5✔
195
            ut_free(from) ;
5✔
196
            ut_free(to) ;
5✔
197
            if ( !conversion_factor ) {
5✔
198
                std::ostringstream oss;
1✔
199
                oss << "[" << var_name << "] cannot convert units from [" << variable->ref->attr->units
1✔
200
                    << "] to [" << new_units << "]";
1✔
201
                publish(MSG_ERROR, oss.str());
1✔
202
                return -1 ;
1✔
203
            }
204

205
            cv_free(variable->conversion_factor);
4✔
206
            variable->conversion_factor = conversion_factor ;
4✔
207
            free(variable->ref->units);
4✔
208
            variable->ref->units = strdup(new_units.c_str());
4✔
209
        }
210
    }
211
    return(0) ;
4✔
212
}
213

214
int Trick::VariableServerThread::var_exists(std::string in_name) {
4✔
215

216
    char buf1[5] ;
217
    bool error = false ;
4✔
218

219
    unsigned int msg_type ;
220
    REF2* var_ref = ref_attributes(in_name.c_str());
4✔
221

222
    if ( var_ref == (REF2*)NULL ) {
4✔
223
        error = true;
2✔
224
    }
225

226
    if (binary_data) {
4✔
227
        /* send binary 1 or 0 */
228
        msg_type = VS_VAR_EXISTS ;
2✔
229
        memcpy(buf1, &msg_type , sizeof(msg_type)) ;
2✔
230

231
        buf1[4] = (error==false);
2✔
232

233
        if (debug >= 2) {
2✔
234
            message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending 1 binary byte\n", &connection, connection.client_tag);
×
235
        }
236
        tc_write(&connection, (char *) buf1, 5);
2✔
237
    } else {
238
        /* send ascii "1" or "0" */
239
        snprintf(buf1, sizeof(buf1), "%d\t%d\n", VS_VAR_EXISTS, (error==false));
2✔
240
        if (debug >= 2) {
2✔
241
            message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending:\n%s\n", &connection, connection.client_tag, buf1) ;
×
242
        }
243
        tc_write(&connection, (char *) buf1, strlen(buf1));
2✔
244
    }
245

246
    return(0) ;
4✔
247
}
248

249
int Trick::VariableServerThread::var_clear() {
22✔
250
    while( !vars.empty() ) {
22✔
251
        delete vars.back();
17✔
252
        vars.pop_back();
17✔
253
    }
254
    return(0) ;
5✔
255
}
256

257

258
int Trick::VariableServerThread::var_send() {
1✔
259
    copy_sim_data();
1✔
260
    write_data();
1✔
261
    return(0) ;
1✔
262
}
263

264
int Trick::VariableServerThread::var_cycle(double in_rate) {
4✔
265
    update_rate = in_rate ;
4✔
266
    cycle_tics = (long long)(update_rate * exec_get_time_tic_value()) ;
4✔
267
    return(0) ;
4✔
268
}
269

270
bool Trick::VariableServerThread::get_pause() {
×
271
    return pause_cmd ;
×
272
}
273

274
void Trick::VariableServerThread::set_pause( bool on_off) {
20✔
275
    pause_cmd = on_off ;
20✔
276
}
20✔
277

278
int Trick::VariableServerThread::var_exit() {
20✔
279
    exit_cmd = true ;
20✔
280
    return(0) ;
20✔
281
}
282

283
int Trick::VariableServerThread::var_validate_address(bool on_off) {
×
284
    validate_address = on_off ;
×
285
    return(0) ;
×
286
}
287

288
int Trick::VariableServerThread::var_debug(int level) {
×
289
    debug = level ;
×
290
    return(0) ;
×
291
}
292

293
int Trick::VariableServerThread::var_ascii() {
×
294
    binary_data = 0 ;
×
295
    return(0) ;
×
296
}
297

298
int Trick::VariableServerThread::var_binary() {
3✔
299
    binary_data = 1 ;
3✔
300
    return(0) ;
3✔
301
}
302

303
int Trick::VariableServerThread::var_binary_nonames() {
1✔
304
    binary_data = 1 ;
1✔
305
    binary_data_nonames = 1 ;
1✔
306
    return(0) ;
1✔
307
}
308

309
int Trick::VariableServerThread::var_set_copy_mode(int mode) {
7✔
310
    if ( mode >= VS_COPY_ASYNC and mode <= VS_COPY_TOP_OF_FRAME ) {
7✔
311
        copy_mode = (VS_COPY_MODE)mode ;
7✔
312
        if ( copy_mode == VS_COPY_SCHEDULED ) {
7✔
313
            long long sim_time_tics ;
314
            sim_time_tics = exec_get_time_tics() ;
3✔
315
            // round the next call time to a multiple of the cycle
316
            sim_time_tics -= sim_time_tics % cycle_tics ;
3✔
317
            next_tics = sim_time_tics + cycle_tics ;
3✔
318

319
            sim_time_tics = exec_get_freeze_time_tics() ;
3✔
320
            // round the next call time to a multiple of the cycle
321
            sim_time_tics -= sim_time_tics % cycle_tics ;
3✔
322
            freeze_next_tics = sim_time_tics + cycle_tics ;
3✔
323

324
        } else {
325
            next_tics = TRICK_MAX_LONG_LONG ;
4✔
326
        }
327
        return 0 ;
7✔
328
    }
329
    return -1 ;
×
330
}
331

332
int Trick::VariableServerThread::var_set_write_mode(int mode) {
4✔
333
    if ( mode >= VS_WRITE_ASYNC and mode <= VS_WRITE_WHEN_COPIED ) {
4✔
334
        write_mode = (VS_WRITE_MODE)mode ;
4✔
335
        return 0 ;
4✔
336
    }
337
    return -1 ;
×
338
}
339

340
int Trick::VariableServerThread::var_sync(int mode) {
×
341

342
    switch (mode) {
×
343
        case 1:
×
344
            var_set_copy_mode(VS_COPY_SCHEDULED) ;
×
345
            var_set_write_mode(VS_WRITE_ASYNC) ;
×
346
            break ;
×
347
        case 2:
×
348
            var_set_copy_mode(VS_COPY_SCHEDULED) ;
×
349
            var_set_write_mode(VS_WRITE_WHEN_COPIED) ;
×
350
            break ;
×
351
        case 0:
×
352
        default:
353
            var_set_copy_mode(VS_COPY_ASYNC) ;
×
354
            var_set_write_mode(VS_WRITE_ASYNC) ;
×
355
            break ;
×
356
    }
357

358
    return 0 ;
×
359
}
360

361
int Trick::VariableServerThread::var_set_frame_multiple(unsigned int mult) {
2✔
362
    frame_multiple = mult ;
2✔
363
    return 0 ;
2✔
364
}
365

366
int Trick::VariableServerThread::var_set_frame_offset(unsigned int offset) {
2✔
367
    frame_offset = offset ;
2✔
368
    return 0 ;
2✔
369
}
370

371
int Trick::VariableServerThread::var_set_freeze_frame_multiple(unsigned int mult) {
1✔
372
    freeze_frame_multiple = mult ;
1✔
373
    return 0 ;
1✔
374
}
375

376
int Trick::VariableServerThread::var_set_freeze_frame_offset(unsigned int offset) {
1✔
377
    freeze_frame_offset = offset ;
1✔
378
    return 0 ;
1✔
379
}
380

381
int Trick::VariableServerThread::var_byteswap(bool on_off) {
×
382
    byteswap = on_off ;
×
383
    return(0) ;
×
384
}
385

386
bool Trick::VariableServerThread::get_send_stdio() {
1✔
387
    return send_stdio ;
1✔
388
}
389

390
int Trick::VariableServerThread::set_send_stdio(bool on_off) {
1✔
391
    send_stdio = on_off ;
1✔
392
    return(0) ;
1✔
393
}
394

395
int Trick::VariableServerThread::var_signal() {
×
396

397
    message_publish(MSG_ERROR,"Variable Server Error: var_signal is currently not implemented.\n") ;
×
398

399
    return(0) ;
×
400
}
401

402
int Trick::VariableServerThread::var_multicast(bool on_off) {
×
403

404
    multicast = on_off ;
×
405

406
    message_publish(MSG_ERROR, "Variable Server Error: var_multicast is currently not implemented.\n") ;
×
407

408
    return(0) ;
×
409
}
410

411
int Trick::VariableServerThread::send_list_size() {
3✔
412
    char buf1[12] ;
413
    unsigned int msg_type ;
414
    int var_count;
415

416
    // send number of variables
417
    var_count = vars.size();
3✔
418
    if (binary_data) {
3✔
419
        // send in the binary message header format:
420
        // <message_indicator><message_size><number_of_variables>
421
        msg_type = VS_LIST_SIZE;
1✔
422
        memcpy(buf1, &msg_type , sizeof(msg_type)) ;
1✔
423

424
        memset(&(buf1[4]), 0, sizeof(int)); // message size = 0
1✔
425
        memcpy(&(buf1[8]), &var_count, sizeof(var_count));
1✔
426

427
        if (debug >= 2) {
1✔
428
            message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending %d event variables\n", &connection, connection.client_tag, var_count);
×
429
        }
430
        tc_write(&connection, (char *) buf1, 12);
1✔
431
    } else {
432
        // ascii
433
        snprintf(buf1, sizeof(buf1), "%d\t%d\n", VS_LIST_SIZE, var_count);
2✔
434
        if (debug >= 2) {
2✔
435
            message_publish(MSG_DEBUG, "%p tag=<%s> var_server sending number of event variables:\n%s\n", &connection, connection.client_tag, buf1) ;
×
436
        }
437
        tc_write(&connection, (char *) buf1, strlen(buf1));
2✔
438
    }
439

440
    return 0 ;
3✔
441
}
442

443
int Trick::VariableServerThread::transmit_file(std::string sie_file) {
×
444
    const unsigned int packet_size = 4095 ;
×
445
    FILE * fp ;
446
    unsigned int file_size ;
447
    unsigned int current_size = 0 ;
×
448
    unsigned int bytes_read ;
449
    char buffer[packet_size] ;
450
    int ret ;
451

452
    if (debug >= 2) {
×
453
        message_publish(MSG_DEBUG,"%p tag=<%s> var_server opening %s.\n", &connection, connection.client_tag, sie_file.c_str()) ;
×
454
    }
455

456
    if ((fp = fopen(sie_file.c_str() , "r")) == NULL ) {
×
457
        message_publish(MSG_ERROR,"Variable Server Error: Cannot open %s.\n", sie_file.c_str()) ;
×
458
        snprintf(buffer, sizeof(buffer), "%d\t-1\n", VS_SIE_RESOURCE) ;
×
459
        tc_write(&connection , buffer , strlen(buffer)) ;
×
460
        return(-1) ;
×
461
    }
462

463
    fseek(fp , 0L, SEEK_END) ;
×
464
    file_size = ftell(fp) ;
×
465

466
    snprintf(buffer, sizeof(buffer), "%d\t%u\n" , VS_SIE_RESOURCE, file_size) ;
×
467
    tc_write(&connection , buffer , strlen(buffer)) ;
×
468
    rewind(fp) ;
×
469

470
    // Switch to blocking writes since this could be a large transfer.
471
    if (tc_blockio(&connection, TC_COMM_BLOCKIO)) {
×
472
        message_publish(MSG_DEBUG,"Variable Server Error: Failed to set TCDevice to TC_COMM_BLOCKIO.\n");
×
473
    }
474

475
    while ( current_size < file_size ) {
×
476
        bytes_read = fread(buffer , 1 , packet_size , fp) ;
×
477
        ret = tc_write(&connection , buffer , bytes_read ) ;
×
478
        if (ret != (int)bytes_read) {
×
479
            message_publish(MSG_ERROR,"Variable Server Error: Failed to send SIE file.\n", sie_file.c_str()) ;
×
480
            return(-1);
×
481
        }
482
        current_size += bytes_read ;
×
483
    }
484

485
    // Switch back to non-blocking writes.
486
    if (tc_blockio(&connection, TC_COMM_NOBLOCKIO)) {
×
487
        message_publish(MSG_ERROR,"Variable Server Error: Failed to set TCDevice to TC_COMM_NOBLOCKIO.\n");
×
488
        return(-1);
×
489
    }
490

491
    return(0) ;
×
492
}
493

494
int Trick::VariableServerThread::send_file(std::string file_name) {
×
495
    return transmit_file(file_name) ;
×
496
}
497

498
int Trick::VariableServerThread::send_sie_resource() {
×
499
    sie_append_runtime_objs() ;
×
500
    return transmit_file(std::string(command_line_args_get_default_dir()) + "/S_sie.resource") ;
×
501
}
502

503
int Trick::VariableServerThread::send_sie_class() {
×
504
    sie_class_attr_map_print_xml() ;
×
505
    return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_class.xml") ;
×
506
}
507

508
int Trick::VariableServerThread::send_sie_enum() {
×
509
    sie_enum_attr_map_print_xml() ;
×
510
    return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_enum.xml") ;
×
511
}
512

513
int Trick::VariableServerThread::send_sie_top_level_objects() {
×
514
    sie_top_level_objects_print_xml() ;
×
515
    return transmit_file(std::string(command_line_args_get_default_dir()) + "/" + "S_sie_top_level_objects.xml") ;
×
516
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc