~ubuntu-branches/debian/jessie/ion/jessie

« back to all changes in this revision

Viewing changes to nm/agent/ingest.c

  • Committer: Package Import Robot
  • Author(s): Leo Iannacone
  • Date: 2013-07-09 16:22:20 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20130709162220-vfrvtfbl78wqzn9x
Tags: 3.2.0~dfsg1-1
* New upstream release.
* Updated debian/ion-tools.pod and debian/ion.links
  with new binaries.
* Updated fix-manpages-errors.patch (closes: #724143).
* Refreshed old patches.
* Removed fix-gcc4.8-errors.patch. Applied to upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 **                           COPYRIGHT NOTICE
 
3
 **      (c) 2012 The Johns Hopkins University Applied Physics Laboratory
 
4
 **                         All rights reserved.
 
5
 **
 
6
 **     This material may only be used, modified, or reproduced by or for the
 
7
 **       U.S. Government pursuant to the license rights granted under
 
8
 **          FAR clause 52.227-14 or DFARS clauses 252.227-7013/7014
 
9
 **
 
10
 **     For any other permissions, please contact the Legal Office at JHU/APL.
 
11
 ******************************************************************************/
 
12
 
 
13
/*****************************************************************************
 
14
 **
 
15
 ** File Name: ingest.h
 
16
 **
 
17
 ** Description: This implements the data ingest thread to receive DTNMP msgs.
 
18
 **
 
19
 ** Notes:
 
20
 **
 
21
 ** Assumptions:
 
22
 **
 
23
 **
 
24
 ** Modification History:
 
25
 **  MM/DD/YY  AUTHOR          DESCRIPTION
 
26
 **  --------  ------------    ---------------------------------------------
 
27
 **  08/31/11  V. Ramachandran Initial Implementation
 
28
 **  01/10/13  E. Birrane      Updates to lastest version of DTNMP spec.
 
29
 **  06/27/13  E. Birrane      Support persisted rules.
 
30
 *****************************************************************************/
 
31
 
 
32
#include "pthread.h"
 
33
 
 
34
#include "platform.h"
 
35
 
 
36
#include "nmagent.h"
 
37
 
 
38
#include "shared/utils/nm_types.h"
 
39
#include "shared/adm/adm.h"
 
40
#include "shared/utils/ion_if.h"
 
41
#include "shared/msg/pdu.h"
 
42
 
 
43
#include "shared/msg/msg_admin.h"
 
44
#include "shared/msg/msg_reports.h"
 
45
#include "shared/msg/msg_def.h"
 
46
#include "shared/msg/msg_ctrl.h"
 
47
#include "shared/primitives/rules.h"
 
48
#include "shared/primitives/instr.h"
 
49
 
 
50
#include "shared/utils/utils.h"
 
51
 
 
52
#include "ingest.h"
 
53
 
 
54
extern eid_t manager_eid;
 
55
 
 
56
/******************************************************************************
 
57
 *
 
58
 * \par Function Name: rx_validate_mid_mc
 
59
 *
 
60
 * \par Determine whether a lyst contains valid, recognized MIDs.
 
61
 *
 
62
 * \param[in]  mids       The list of mids to validate.
 
63
 * \param[in]  passEmpty  Whether an empty list is OK (1) or not (0)
 
64
 *
 
65
 * \par Notes:
 
66
 *   - A NULL list is always bad.
 
67
 *
 
68
 * \return 0 - Lyst failed to validate.
 
69
 *         !0 - Valid lyst.
 
70
 *
 
71
 * Modification History:
 
72
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
73
 *  --------  ------------   ---------------------------------------------
 
74
 *  01/10/13  E. Birrane     Initial implementation.
 
75
 *****************************************************************************/
 
76
 
 
77
int rx_validate_mid_mc(Lyst mids, int passEmpty)
 
78
{
 
79
    LystElt elt;
 
80
    mid_t *cur_mid = NULL;
 
81
    int i = 0;
 
82
 
 
83
    DTNMP_DEBUG_ENTRY("rx_validate_mid_mc","(0x%#llx, %d)",
 
84
                         (unsigned long) mids, passEmpty);
 
85
 
 
86
    /* Step 0 : Sanity Check. */
 
87
    if (mids == NULL)
 
88
    {
 
89
        DTNMP_DEBUG_ERR("rx_validate_mid_mc", "Bad Args.", NULL);
 
90
        DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL);
 
91
        return 0;
 
92
    }
 
93
 
 
94
    /* Step 1: Walk the list of MIDs. */
 
95
    for (elt = lyst_first(mids); elt; elt = lyst_next(elt))
 
96
    {
 
97
        i++;
 
98
 
 
99
        /* Grab the next mid...*/
 
100
        if((cur_mid = (mid_t*) lyst_data(elt)) == NULL)
 
101
        {
 
102
            DTNMP_DEBUG_ERR("rx_validate_mid_mc","Found unexpected NULL mid.", NULL);
 
103
            DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL);
 
104
            return 0;
 
105
        }
 
106
 
 
107
        char *mid_str = mid_to_string(cur_mid);
 
108
 
 
109
        /* Is this a valid MID? */
 
110
        if(mid_sanity_check(cur_mid) == 0)
 
111
        {
 
112
            DTNMP_DEBUG_ERR("rx_validate_mid_mc","Malformed MID: %s.", mid_str);
 
113
            MRELEASE(mid_str);
 
114
            DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL);
 
115
            return 0;
 
116
        }
 
117
 
 
118
        /* Do we know this MID? */
 
119
        if((adm_find_datadef(cur_mid) == NULL) &&
 
120
           (def_find_by_id(gAgentVDB.reports, &(gAgentVDB.reports_mutex), cur_mid) == NULL))
 
121
        {
 
122
            DTNMP_DEBUG_ERR("rx_validate_mid_mc","Unknown MID %s.", mid_str);
 
123
            MRELEASE(mid_str);
 
124
            DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL);
 
125
            return 0;
 
126
        }
 
127
 
 
128
        DTNMP_DEBUG_INFO("rx_validate_mid_mc","MID %s is recognized.", mid_str);
 
129
 
 
130
        MRELEASE(mid_str);
 
131
    }
 
132
 
 
133
 
 
134
    if((i == 0) && (passEmpty == 0))
 
135
    {
 
136
        DTNMP_DEBUG_ERR("rx_validate_mid_mc","Empty MID list not allowed.", NULL);
 
137
        DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 0", NULL);
 
138
        return 0;
 
139
    }
 
140
 
 
141
    DTNMP_DEBUG_EXIT("rx_validate_mid_mc","-> 1", NULL);
 
142
    return 1;
 
143
}
 
144
 
 
145
 
 
146
 
 
147
/******************************************************************************
 
148
 *
 
149
 * \par Function Name: rx_validate_rule
 
150
 *
 
151
 * \par Determines whether a production rule is correct.
 
152
 *
 
153
 * \param[in] rule  The rule being evaluated.
 
154
 *
 
155
 * \return 0 - Bad rule.
 
156
 *                 1 - Good rule.
 
157
 *
 
158
 * Modification History:
 
159
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
160
 *  --------  ------------   ---------------------------------------------
 
161
 *  01/10/13  E. Birrane     Initial implementation.
 
162
 *****************************************************************************/
 
163
 
 
164
int rx_validate_rule(rule_time_prod_t *rule)
 
165
{
 
166
    int result = 1;
 
167
    
 
168
    DTNMP_DEBUG_ENTRY("rx_validate_rule","(0x%x)", (unsigned long) rule);
 
169
 
 
170
    /* Step 0: Sanity Check. */
 
171
    if(rule == NULL)
 
172
    {
 
173
        DTNMP_DEBUG_ERR("rx_validate_rule","NULL rule.", NULL);
 
174
        DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL);
 
175
        return 0;
 
176
    }
 
177
 
 
178
    /* Is the interval correct? */
 
179
    if(rule->desc.interval_ticks == 0)
 
180
    {
 
181
        DTNMP_DEBUG_ERR("rx_validate_rule","Bad interval ticks: 0.", NULL);
 
182
        DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL);
 
183
        return 0;
 
184
    }
 
185
 
 
186
    /* Do we understand the sender EID? */
 
187
    if(memcmp(&(rule->desc.sender), &(manager_eid), MAX_EID_LEN) != 0)
 
188
    {
 
189
        DTNMP_DEBUG_ERR("rx_validate_rule","Unknown EID: %s.", rule->desc.sender.name);
 
190
        DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL);
 
191
        return 0;
 
192
    }
 
193
 
 
194
    /* Is each MID valid and recognized? */
 
195
    if(rx_validate_mid_mc(rule->mids, 0) == 0)
 
196
    {
 
197
        DTNMP_DEBUG_ERR("rx_validate_rule","Unknown MIDs",NULL);
 
198
        DTNMP_DEBUG_EXIT("rx_validate_rule","-> 0", NULL);
 
199
        return 0;
 
200
    }
 
201
 
 
202
        DTNMP_DEBUG_EXIT("rx_validate_rule","-> 1", NULL);
 
203
 
 
204
    return result;
 
205
}
 
206
 
 
207
 
 
208
 
 
209
/******************************************************************************
 
210
 *
 
211
 * \par Function Name: rx_thread
 
212
 *
 
213
 * \par Receives and processes a DTNMP message.
 
214
 *
 
215
 * \param[in] threadId The thread identifier.
 
216
 *
 
217
 * \return NULL - Error
 
218
 *         !NULL - Some thread thing.
 
219
 *
 
220
 * Modification History:
 
221
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
222
 *  --------  ------------   ---------------------------------------------
 
223
 *  01/10/13  E. Birrane     Initial implementation.
 
224
 *****************************************************************************/
 
225
 
 
226
void *rx_thread(void *threadId) {
 
227
   
 
228
    DTNMP_DEBUG_ENTRY("rx_thread","(0x%x)",(unsigned long) threadId);
 
229
    
 
230
    DTNMP_DEBUG_INFO("rx_thread","Receiver thread running...", NULL);
 
231
    
 
232
    uint32_t num_msgs = 0;
 
233
    uint8_t *buf = NULL;
 
234
    uint8_t *cursor = NULL;
 
235
    uint32_t bytes = 0;
 
236
    uint32_t i = 0;
 
237
    pdu_header_t *hdr = NULL;
 
238
    pdu_acl_t *acl = NULL;
 
239
    uint32_t size = 0;
 
240
    pdu_metadata_t meta;
 
241
    uvast val = 0;
 
242
    time_t group_timestamp = 0;
 
243
 
 
244
    /* 
 
245
     * g_running controls the overall execution of threads in the
 
246
     * NM Agent.
 
247
     */
 
248
    while(g_running) {
 
249
        
 
250
        /* Step 1: Receive a message from the Bundle Protocol Agent. */
 
251
        buf = iif_receive(&ion_ptr, &size, &meta, NM_RECEIVE_TIMEOUT_SEC);
 
252
 
 
253
        if(buf != NULL)
 
254
        {
 
255
            DTNMP_DEBUG_INFO("rx_thread","Received buf (%x) of size %d",
 
256
                                 (unsigned long) buf, size);
 
257
 
 
258
            /* Grab # messages and timestamp for this group. */
 
259
            cursor = buf;
 
260
 
 
261
            bytes = utils_grab_sdnv(cursor, size, &val);
 
262
            num_msgs = val;
 
263
            cursor += bytes;
 
264
            size -= bytes;
 
265
 
 
266
            bytes = utils_grab_sdnv(cursor, size, &val);
 
267
            group_timestamp = val;
 
268
            cursor += bytes;
 
269
            size -= bytes;
 
270
 
 
271
            DTNMP_DEBUG_INFO("rx_thread","Group had %d msgs", num_msgs);
 
272
            DTNMP_DEBUG_INFO("rx_thread","Group time stamp %lu", (unsigned long) group_timestamp);
 
273
 
 
274
            /* For each message in the bundle. */
 
275
            for(i = 0; i < num_msgs; i++)
 
276
            {
 
277
                hdr = pdu_deserialize_hdr(cursor, size, &bytes);
 
278
                cursor += bytes;
 
279
                size -= bytes;
 
280
 
 
281
                switch (hdr->id)
 
282
                {
 
283
                        case MSG_TYPE_CTRL_PERIOD_PROD:
 
284
                        {
 
285
                                DTNMP_DEBUG_ALWAYS("NM Agent :","Received Periodic Production Message.\n", NULL);
 
286
                                rx_handle_time_prod(&meta, cursor,size,&bytes);
 
287
                        }
 
288
                        break;
 
289
                
 
290
                        case MSG_TYPE_DEF_CUST_RPT:
 
291
                        {
 
292
                                DTNMP_DEBUG_ALWAYS("NM Agent :","Received Custom Report Definition.\n", NULL);
 
293
                                rx_handle_rpt_def(&meta, cursor,size,&bytes);
 
294
                        }
 
295
                        break;
 
296
 
 
297
                        case MSG_TYPE_CTRL_EXEC:
 
298
                        {
 
299
                                DTNMP_DEBUG_ALWAYS("NM Agent :","Received Perform Control Message.\n", NULL);
 
300
                                rx_handle_exec(&meta, cursor,size,&bytes);
 
301
                        }
 
302
                        break;
 
303
 
 
304
                        case MSG_TYPE_DEF_MACRO:
 
305
                        {
 
306
                                DTNMP_DEBUG_ALWAYS("NM Agent :","Received Macro Definition.\n", NULL);
 
307
                                rx_handle_macro_def(&meta, cursor,size,&bytes);
 
308
                        }
 
309
                        break;
 
310
 
 
311
                        default:
 
312
                        {
 
313
                                DTNMP_DEBUG_WARN("rx_thread","Received unknown type: %d.\n", hdr->type);
 
314
                                DTNMP_DEBUG_ALWAYS("NM Agent :","Received Unsupported message of type 0x%x.\n", hdr->id);
 
315
 
 
316
                        }
 
317
                        break;
 
318
                }
 
319
            }
 
320
        }
 
321
    }
 
322
   
 
323
    DTNMP_DEBUG_ALWAYS("rx_thread","Shutting Down Agent Receive Thread.",NULL);
 
324
    DTNMP_DEBUG_EXIT("rx_thread","->.", NULL);
 
325
    pthread_exit(NULL);
 
326
}
 
327
 
 
328
 
 
329
/******************************************************************************
 
330
 *
 
331
 * \par Function Name: rx_handle_rpt_def
 
332
 *
 
333
 * \par Process a received custom report definition message. This function
 
334
 *      accepts a portion of a serialized message group, with the
 
335
 *      understanding that the custom report definition message is at the
 
336
 *      head of the serialized data stream.  This function extracts the
 
337
 *      current message, and returns the number of bytes consumed so that
 
338
 *      the called may then know where the next message in the serialized
 
339
 *      message group begins.
 
340
 *
 
341
 * \param[in] meta        The metadata associated with the message.
 
342
 * \param[in] cursor      Pointer to the start of the serialized message.
 
343
 * \param[in] size        The size of the remaining serialized message group
 
344
 * \param[out] bytes_used The number of bytes consumed in processing this msg.
 
345
 *
 
346
 * Modification History:
 
347
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
348
 *  --------  ------------   ---------------------------------------------
 
349
 *  01/10/13  E. Birrane     Initial implementation.
 
350
 *****************************************************************************/
 
351
 
 
352
void rx_handle_rpt_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used)
 
353
{
 
354
        def_gen_t* rpt_def = NULL;
 
355
        uint32_t bytes = 0;
 
356
 
 
357
        DTNMP_DEBUG_ENTRY("rx_handle_rpt_def","(0x%#llx, %d, 0x%#llx)",
 
358
                                  (unsigned long)cursor, size, (unsigned long) bytes_used);
 
359
 
 
360
        /* Step 0: Sanity checks. */
 
361
        if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL))
 
362
        {
 
363
        DTNMP_DEBUG_ERR("rx_handle_rpt_def","Bad args.",NULL);
 
364
        DTNMP_DEBUG_EXIT("rx_handle_rpt_def","->.",NULL);
 
365
        return;
 
366
        }
 
367
 
 
368
        /* Step 1: Attempt to deserialize the message. */
 
369
    rpt_def = def_deserialize_gen(cursor, size, &bytes);
 
370
 
 
371
    /* Step 2: If the deserialization failed, complain. */
 
372
    if((rpt_def == NULL) || (bytes == 0))
 
373
    {
 
374
        DTNMP_DEBUG_ERR("rx_handle_rpt_def","Can't deserialize.",NULL);
 
375
        def_release_gen(rpt_def);
 
376
        *bytes_used = 0;
 
377
        DTNMP_DEBUG_EXIT("rx_handle_rpt_def","->.",NULL);
 
378
        return;
 
379
    }
 
380
 
 
381
    /* Step 3: Otherwise, note how many bytes were consumed. */
 
382
    *bytes_used = bytes;
 
383
 
 
384
        DTNMP_DEBUG_INFO("rx_handle_rpt_def","Adding new report definition.", NULL);
 
385
 
 
386
 
 
387
    /* Step 4: Persist this definition to our SDR. */
 
388
    agent_db_report_persist(rpt_def);
 
389
 
 
390
    /* Step 5: Persist this definition to our memory lists. */
 
391
//      agent_vdb_reports_init(getIonsdr());
 
392
        ADD_REPORT(rpt_def);
 
393
 
 
394
        /* Step 6: Update instrumentation counters. */
 
395
        gAgentInstr.num_rpt_defs++;
 
396
}
 
397
 
 
398
 
 
399
 
 
400
/******************************************************************************
 
401
 *
 
402
 * \par Function Name: rx_handle_exec
 
403
 *
 
404
 * \par Process a received control exec  message. This function
 
405
 *      accepts a portion of a serialized message group, with the
 
406
 *      understanding that the control exec message is at the
 
407
 *      head of the serialized data stream.  This function extracts the
 
408
 *      current message, and returns the number of bytes consumed so that
 
409
 *      the called may then know where the next message in the serialized
 
410
 *      message group begins.
 
411
 *
 
412
 * \param[in] meta        The metadata associated with the message.
 
413
 * \param[in] cursor      Pointer to the start of the serialized message.
 
414
 * \param[in] size        The size of the remaining serialized message group
 
415
 * \param[out] bytes_used The number of bytes consumed in processing this msg.
 
416
 *
 
417
 * Modification History:
 
418
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
419
 *  --------  ------------   ---------------------------------------------
 
420
 *  01/10/13  E. Birrane     Initial implementation.
 
421
 *****************************************************************************/
 
422
 
 
423
void rx_handle_exec(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used)
 
424
{
 
425
        ctrl_exec_t* ctrl = NULL;
 
426
        uint32_t bytes = 0;
 
427
 
 
428
        DTNMP_DEBUG_ENTRY("rx_handle_exec","(0x%#llx, %d, 0x%#llx)",
 
429
                                  (unsigned long)cursor, size, (unsigned long) bytes_used);
 
430
 
 
431
 
 
432
        /* Step 0: Sanity checks. */
 
433
        if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL))
 
434
        {
 
435
        DTNMP_DEBUG_ERR("rx_handle_exec","Bad args.",NULL);
 
436
        DTNMP_DEBUG_EXIT("rx_handle_exec","->.",NULL);
 
437
        return;
 
438
        }
 
439
 
 
440
        /* Step 1: Attempt to deserialize the message. */
 
441
        ctrl = ctrl_deserialize_exec(cursor, size, &bytes);
 
442
 
 
443
        /* Step 2: If the deserialization failed, complain. */
 
444
    if((ctrl == NULL) || (bytes == 0))
 
445
    {
 
446
        DTNMP_DEBUG_ERR("rx_handle_exec","Can't deserialize.",NULL);
 
447
        ctrl_release_exec(ctrl);
 
448
        *bytes_used = 0;
 
449
        DTNMP_DEBUG_EXIT("rx_handle_exec","->.",NULL);
 
450
        return;
 
451
    }
 
452
 
 
453
    /* Step 3: Otherwise, note how many bytes were consumed. */
 
454
    *bytes_used = bytes;
 
455
 
 
456
 
 
457
    /*
 
458
     * Step 4: Adjust the countdown ticks based on whether
 
459
     *         we are given a relative or absolute time.
 
460
     */
 
461
 
 
462
    if(ctrl->time <= DTNMP_RELATIVE_TIME_EPOCH)
 
463
    {
 
464
        /* Step 4a: If relative time, that is # seconds. */
 
465
        ctrl->countdown_ticks = ctrl->time;
 
466
    }
 
467
    else
 
468
    {
 
469
        /*
 
470
         * Step 4b: If absolute time, # seconds if difference
 
471
         * from now until then.
 
472
         */
 
473
        ctrl->countdown_ticks = (ctrl->time - getUTCTime());
 
474
    }
 
475
 
 
476
    /* Step 5: Populate dynamic parts of the control. */
 
477
        ctrl->desc.state = CONTROL_ACTIVE;
 
478
        strcpy(ctrl->desc.sender.name, meta->senderEid.name);
 
479
 
 
480
    /* Step 6: Persist this definition to our SDR. */
 
481
    agent_db_ctrl_persist(ctrl);
 
482
 
 
483
    /* Step 7: Persist this definition to our memory lists. */
 
484
        DTNMP_DEBUG_INFO("rx_handle_exec","Performing control.", NULL);
 
485
        ADD_CTRL(ctrl);
 
486
 
 
487
        /* Step 8: Update instrumentation counters. */
 
488
        gAgentInstr.num_ctrls++;
 
489
 
 
490
}
 
491
 
 
492
 
 
493
/******************************************************************************
 
494
 *
 
495
 * \par Function Name: rx_handle_time_prod
 
496
 *
 
497
 * \par Process a received time-based prod message. This function
 
498
 *      accepts a portion of a serialized message group, with the
 
499
 *      understanding that the time-based prod message is at the
 
500
 *      head of the serialized data stream.  This function extracts the
 
501
 *      current message, and returns the number of bytes consumed so that
 
502
 *      the called may then know where the next message in the serialized
 
503
 *      message group begins.
 
504
 *
 
505
 * \param[in] meta        The metadata associated with the message.
 
506
 * \param[in] cursor      Pointer to the start of the serialized message.
 
507
 * \param[in] size        The size of the remaining serialized message group
 
508
 * \param[out] bytes_used The number of bytes consumed in processing this msg.
 
509
 *
 
510
 * Modification History:
 
511
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
512
 *  --------  ------------   ---------------------------------------------
 
513
 *  01/10/13  E. Birrane     Initial implementation.
 
514
 *****************************************************************************/
 
515
 
 
516
void rx_handle_time_prod(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used)
 
517
{
 
518
        rule_time_prod_t *new_rule = NULL;
 
519
    uint32_t bytes = 0;
 
520
 
 
521
    DTNMP_DEBUG_INFO("rx_handle_time_prod",
 
522
                         "Processing a production rule.", NULL);
 
523
 
 
524
        /* Step 0: Sanity checks. */
 
525
        if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL))
 
526
        {
 
527
        DTNMP_DEBUG_ERR("rx_handle_time_prod","Bad args.",NULL);
 
528
        DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL);
 
529
        return;
 
530
        }
 
531
 
 
532
        /* Step 1: Attempt to deserialize the message. */
 
533
        new_rule = ctrl_deserialize_time_prod_entry(cursor, size, &bytes);
 
534
 
 
535
        /* Step 2: If the deserialization failed, complain. */
 
536
        if((new_rule == NULL) || (bytes == 0))
 
537
        {
 
538
                DTNMP_DEBUG_ERR("rx_handle_time_prod","Can't deserialize.",NULL);
 
539
                rule_release_time_prod_entry(new_rule);
 
540
                *bytes_used = 0;
 
541
                DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL);
 
542
                return;
 
543
        }
 
544
 
 
545
    /* Step 3: Otherwise, note how many bytes were consumed. */
 
546
    *bytes_used = bytes;
 
547
 
 
548
    /* Step 4: Populate dynamic parts of the control. */
 
549
    /* \todo: Consider single-fire absolute-time rules. */
 
550
    new_rule->desc.num_evals = new_rule->count;
 
551
    new_rule->desc.interval_ticks = new_rule->period;
 
552
    new_rule->countdown_ticks = new_rule->desc.interval_ticks;
 
553
 
 
554
    strcpy(new_rule->desc.sender.name, meta->senderEid.name);
 
555
 
 
556
    if(new_rule->desc.num_evals == 0)
 
557
    {
 
558
        new_rule->desc.num_evals = DTNMP_RULE_EXEC_ALWAYS;
 
559
    }
 
560
 
 
561
    /* Step 5: Validate the new rule. */
 
562
    if(rx_validate_rule(new_rule) == 0)
 
563
    {
 
564
                DTNMP_DEBUG_ERR("rx_handle_time_prod","New rule failed validation.",NULL);
 
565
                rule_release_time_prod_entry(new_rule);
 
566
                *bytes_used = 0;
 
567
                DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL);
 
568
                return;
 
569
    }
 
570
 
 
571
    DTNMP_DEBUG_INFO("rx_handle_time_prod",
 
572
                                 "Adding new production rule.", NULL);
 
573
 
 
574
    /* Step 6: Persist this definition to our SDR. */
 
575
    agent_db_rule_persist(new_rule);
 
576
 
 
577
    /* Step 7: Persist this definition to our memory lists. */
 
578
        ADD_RULE(new_rule);
 
579
 
 
580
        /* Step 8: Update instrumentation counters. */
 
581
        gAgentInstr.num_time_rules++;
 
582
}
 
583
 
 
584
 
 
585
 
 
586
 
 
587
/******************************************************************************
 
588
 *
 
589
 * \par Function Name: rx_handle_macro_def
 
590
 *
 
591
 * \par Process a received macro def message. This function
 
592
 *      accepts a portion of a serialized message group, with the
 
593
 *      understanding that the macro def message is at the
 
594
 *      head of the serialized data stream.  This function extracts the
 
595
 *      current message, and returns the number of bytes consumed so that
 
596
 *      the called may then know where the next message in the serialized
 
597
 *      message group begins.
 
598
 *
 
599
 * \param[in] meta        The metadata associated with the message.
 
600
 * \param[in] cursor      Pointer to the start of the serialized message.
 
601
 * \param[in] size        The size of the remaining serialized message group
 
602
 * \param[out] bytes_used The number of bytes consumed in processing this msg.
 
603
 *
 
604
 * Modification History:
 
605
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 
606
 *  --------  ------------   ---------------------------------------------
 
607
 *  01/10/13  E. Birrane     Initial implementation.
 
608
 *****************************************************************************/
 
609
void rx_handle_macro_def(pdu_metadata_t *meta, uint8_t *cursor, uint32_t size, uint32_t *bytes_used)
 
610
{
 
611
        def_gen_t* macro_def = NULL;
 
612
        uint32_t bytes = 0;
 
613
 
 
614
        DTNMP_DEBUG_ENTRY("rx_handle_macro_def","(0x%x, %d, 0x%x)",
 
615
                                  (unsigned long)cursor, size, (unsigned long) bytes_used);
 
616
 
 
617
 
 
618
        /* Step 0: Sanity checks. */
 
619
        if((meta == NULL) || (cursor == NULL) || (bytes_used == NULL))
 
620
        {
 
621
        DTNMP_DEBUG_ERR("rx_handle_time_prod","Bad args.",NULL);
 
622
        DTNMP_DEBUG_EXIT("rx_handle_time_prod","->.",NULL);
 
623
        return;
 
624
        }
 
625
 
 
626
        /* Step 1: Attempt to deserialize the message. */
 
627
    macro_def = def_deserialize_gen(cursor, size, &bytes);
 
628
 
 
629
        /* Step 2: If the deserialization failed, complain. */
 
630
    if((macro_def == NULL) || (bytes == 0))
 
631
    {
 
632
        DTNMP_DEBUG_ERR("rx_handle_macro_def","Can;t deserialize.",NULL);
 
633
        def_release_gen(macro_def);
 
634
        *bytes_used = 0;
 
635
        DTNMP_DEBUG_EXIT("rx_handle_macro_def","->.",NULL);
 
636
        return;
 
637
    }
 
638
 
 
639
    /* Step 3: Otherwise, note how many bytes were consumed. */
 
640
    *bytes_used = bytes;
 
641
 
 
642
        DTNMP_DEBUG_INFO("rx_handle_macro_def","Adding new report definition.", NULL);
 
643
 
 
644
    /* Step 4: Persist this definition to our SDR. */
 
645
        agent_db_macro_persist(macro_def);
 
646
 
 
647
    /* Step 5: Persist this definition to our memory lists. */
 
648
        ADD_MACRO(macro_def);
 
649
 
 
650
        /* Step 6: Update instrumentation counters. */
 
651
        gAgentInstr.num_macros++;
 
652
}
 
653