1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 /**************************************************************************/
12 /**************************************************************************/
13 /**                                                                       */
14 /** NetX MSRP Component                                                   */
15 /**                                                                       */
16 /**   Multiple Stream Registration Protocol (MSRP)                        */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 #include "nx_msrp.h"
22 
23 #ifdef NX_ENABLE_VLAN
24 #ifdef NX_MSRP_DEBUG
25 #ifndef NX_MSRP_DEBUG_PRINTF
26 #define NX_MSRP_DEBUG_PRINTF(x) printf x
27 #endif
28 #else
29 #define NX_MSRP_DEBUG_PRINTF(x)
30 #endif
31 
32 static NX_MSRP_ATTRIBUTE msrp_attribute_array[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE];
33 
34 /**************************************************************************/
35 /*                                                                        */
36 /*  FUNCTION                                               RELEASE        */
37 /*                                                                        */
38 /*    nx_msrp_init                                        PORTABLE C      */
39 /*                                                           6.4.0        */
40 /*  AUTHOR                                                                */
41 /*                                                                        */
42 /*    Wen Wang,  Microsoft Corporation                                    */
43 /*                                                                        */
44 /*  DESCRIPTION                                                           */
45 /*                                                                        */
46 /*    This function initialize MSRP paramter.                             */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    msrp_ptr                              MSRP instance pointer         */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    None                                                                */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    nx_srp_init                           Initialize SRP                */
63 /*                                                                        */
64 /*  RELEASE HISTORY                                                       */
65 /*                                                                        */
66 /*    DATE              NAME                      DESCRIPTION             */
67 /*                                                                        */
68 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
69 /*                                                                        */
70 /**************************************************************************/
nx_msrp_init(NX_MSRP * msrp_ptr)71 UINT nx_msrp_init(NX_MSRP *msrp_ptr)
72 {
73     /* Initialize MSRP structure.*/
74     msrp_ptr -> nx_msrp_participant.participant_type = NX_MRP_PARTICIPANT_MSRP;
75     msrp_ptr -> nx_msrp_participant.protocol_version = NX_MRP_MSRP_PROTOCOL_VERSION;
76     msrp_ptr -> nx_msrp_participant.indication_function = nx_msrp_indication_process;
77     msrp_ptr -> nx_msrp_participant.unpack_function = nx_msrp_mrpdu_parse;
78     msrp_ptr -> nx_msrp_participant.pack_function = nx_msrp_mrpdu_pack;
79 
80     msrp_ptr -> nx_msrp_participant.join_timer = NX_MRP_TIMER_JOIN;
81     msrp_ptr -> nx_msrp_participant.leaveall_timer = NX_MRP_TIMER_LEAVEALL;
82 
83     msrp_ptr -> msrp_callback_data = NX_NULL;
84 
85     return(NX_MSRP_SUCCESS);
86 }
87 
88 /**************************************************************************/
89 /*                                                                        */
90 /*  FUNCTION                                               RELEASE        */
91 /*                                                                        */
92 /*    nx_msrp_attribute_find                              PORTABLE C      */
93 /*                                                           6.4.0        */
94 /*  AUTHOR                                                                */
95 /*                                                                        */
96 /*    Wen Wang,  Microsoft Corporation                                    */
97 /*                                                                        */
98 /*  DESCRIPTION                                                           */
99 /*                                                                        */
100 /*    This function finds an MSRP attribute. Create new one if nothing    */
101 /*    can be find.                                                        */
102 /*  INPUT                                                                 */
103 /*                                                                        */
104 /*    mrp                                   MRP instance pointer          */
105 /*    participant                           MRP participant               */
106 /*    attribute_ptr                         Attribute pointer             */
107 /*    attribute_type                        Attribute type                */
108 /*    attribute_value                       Attribute value               */
109 /*                                                                        */
110 /*  OUTPUT                                                                */
111 /*                                                                        */
112 /*    status                                Completion status             */
113 /*                                                                        */
114 /*  CALLS                                                                 */
115 /*                                                                        */
116 /*    nx_mrp_attribute_new                  Create new mrp attribute      */
117 /*    NX_MSRP_DEBUG_PRINTF                  Printf for debug              */
118 /*    memcpy                                Standard library function     */
119 /*                                                                        */
120 /*  CALLED BY                                                             */
121 /*                                                                        */
122 /*    nx_msrp_register_stream_request       MSRP register stream requset  */
123 /*    nx_msrp_register_attach_request       MSRP register stream attach   */
124 /*    nx_msrp_deregister_stream_request     MSRP deregister stream requset*/
125 /*    nx_msrp_deregister_attach_request     MSRP deregister stream attach */
126 /*    nx_msrp_register_domain_request       MSRP register domain requset  */
127 /*    nx_msrp_deregister_domain_request     MSRP deregister domain requset*/
128 /*    nx_msrp_mrpdu_parse                   MSRP parse MRP date unit      */
129 /*                                                                        */
130 /*  RELEASE HISTORY                                                       */
131 /*                                                                        */
132 /*    DATE              NAME                      DESCRIPTION             */
133 /*                                                                        */
134 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
135 /*                                                                        */
136 /**************************************************************************/
nx_msrp_attribute_find(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE ** attribute_ptr,UCHAR attribute_type,UCHAR * attribute_value)137 UINT nx_msrp_attribute_find(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE **attribute_ptr, UCHAR attribute_type, UCHAR *attribute_value)
138 {
139 NX_MRP_ATTRIBUTE *msrp_attribute;
140 NX_MRP_ATTRIBUTE *tmp;
141 INT               difference;
142 
143 /* Look up attribute_type in attribute array.*/
144 NX_MRP_ATTRIBUTE *attribute_head = participant -> inused_head;
145 
146     while (NX_NULL != attribute_head)
147     {
148         if (attribute_head -> attribute_type == attribute_type)
149         {
150             switch (attribute_type)
151             {
152             case NX_MSRP_TALKER_ADVERTISE_VECTOR:
153 
154                 if (memcmp(((NX_MSRP_ATTRIBUTE *)attribute_head) -> msrp_attribute_union.talker_advertise.stream_id, (UCHAR *)attribute_value, 8) == 0)
155                 {
156                     *attribute_ptr = attribute_head;
157 
158                     return(NX_MSRP_ATTRIBUTE_FOUND);
159                 }
160 
161                 break;
162 
163             case NX_MSRP_TALKER_LISTENER_VECTOR:
164 
165                 if (memcmp(((NX_MSRP_ATTRIBUTE *)attribute_head) -> msrp_attribute_union.listener.stream_id, (UCHAR *)attribute_value, 8) == 0)
166                 {
167 
168                     *attribute_ptr = attribute_head;
169 
170                     return(NX_MSRP_ATTRIBUTE_FOUND);
171                 }
172 
173                 break;
174 
175             case NX_MSRP_TALKER_DOMAIN_VECTOR:
176 
177                 if (((NX_MSRP_ATTRIBUTE *)attribute_head) -> msrp_attribute_union.domain.sr_class_id == *(UCHAR *)attribute_value)
178                 {
179                     *attribute_ptr = attribute_head;
180 
181                     return(NX_MSRP_ATTRIBUTE_FOUND);
182                 }
183                 NX_MSRP_DEBUG_PRINTF(("sr_class_id = %d \r\n", ((NX_MSRP_ATTRIBUTE *)attribute_head) -> msrp_attribute_union.domain.sr_class_id));
184 
185                 NX_MSRP_DEBUG_PRINTF(("attribute_value = %d \r\n", *(UCHAR *)attribute_value));
186 
187                 break;
188 
189             case NX_MSRP_TALKER_FAILED_VECTOR:
190 
191                 if (memcmp(((NX_MSRP_ATTRIBUTE *)attribute_head) -> msrp_attribute_union.talker_advertise.stream_id, (UCHAR *)attribute_value, 8) == 0)
192                 {
193                     *attribute_ptr = attribute_head;
194 
195                     return(NX_MSRP_ATTRIBUTE_FOUND);
196                 }
197 
198                 break;
199 
200             default:
201 
202                 break;
203             }
204 
205             attribute_head = attribute_head -> next;
206         }
207         else
208         {
209             attribute_head = attribute_head -> next;
210         }
211     }
212 
213     *attribute_ptr = nx_mrp_attribute_new(mrp, participant, (NX_MRP_ATTRIBUTE *)msrp_attribute_array, sizeof(NX_MSRP_ATTRIBUTE), NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE);
214 
215     /*Initialize attribute_type and part of attribute value.*/
216     (*attribute_ptr) -> attribute_type = attribute_type;
217 
218     switch ((*attribute_ptr) -> attribute_type)
219     {
220 
221     case NX_MSRP_TALKER_ADVERTISE_VECTOR:
222 
223         memcpy(((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.talker_advertise.stream_id,
224                (UCHAR *)attribute_value, 8); /* use case of memcpy is verified. */
225         break;
226 
227     case NX_MSRP_TALKER_LISTENER_VECTOR:
228 
229         memcpy(((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.listener.stream_id,
230                (UCHAR *)attribute_value, 8); /* use case of memcpy is verified. */
231         break;
232 
233     case NX_MSRP_TALKER_DOMAIN_VECTOR:
234 
235         memcpy(&((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.domain.sr_class_id,
236                (UCHAR *)attribute_value, 1); /* use case of memcpy is verified. */
237         break;
238 
239     case NX_MSRP_TALKER_FAILED_VECTOR:
240     default:
241 
242         return(NX_MSRP_ATTRIBUTE_TYPE_ERROR);
243     }
244 
245 
246     if (*attribute_ptr == NX_NULL)
247     {
248 
249         return(NX_MSRP_ATTRIBUTE_FIND_ERROR);
250     }
251 
252 
253     /* Do insert and sort as attribute type value when needs to create a new one.*/
254     if (participant -> inused_head == NX_NULL)
255     {
256 
257         participant -> inused_head = *attribute_ptr;
258 
259         return(NX_MSRP_ATTRIBUTE_NEW);
260     }
261 
262     msrp_attribute = participant -> inused_head;
263 
264     while (msrp_attribute)
265     {
266         if (((*attribute_ptr) -> attribute_type) > (msrp_attribute -> attribute_type))
267         {
268 
269             tmp = msrp_attribute;
270 
271             msrp_attribute =  msrp_attribute -> next;
272 
273             if (msrp_attribute == NX_NULL)
274             {
275                 tmp -> next = *attribute_ptr;
276                 (*attribute_ptr) -> next = NX_NULL;
277                 return(NX_MSRP_ATTRIBUTE_NEW);
278             }
279 
280             continue;
281         }
282         else if ((*attribute_ptr) -> attribute_type == msrp_attribute -> attribute_type)
283         {
284 
285             while ((*attribute_ptr) -> attribute_type == msrp_attribute -> attribute_type)
286             {
287                 switch ((*attribute_ptr) -> attribute_type)
288                 {
289 
290                 case NX_MSRP_TALKER_ADVERTISE_VECTOR:
291 
292                     difference =  memcmp(((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.talker_advertise.stream_id,
293                                          ((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.talker_advertise.stream_id, 8);
294                     break;
295 
296                 case NX_MSRP_TALKER_LISTENER_VECTOR:
297 
298                     difference =  memcmp(((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.listener.stream_id,
299                                          ((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.listener.stream_id, 8);
300 
301                     break;
302                 case NX_MSRP_TALKER_DOMAIN_VECTOR:
303 
304                     difference =  memcmp(&((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.domain.sr_class_id,
305                                          &((NX_MSRP_ATTRIBUTE *)*attribute_ptr) -> msrp_attribute_union.domain.sr_class_id, 1);
306 
307                     break;
308 
309                 case NX_MSRP_TALKER_FAILED_VECTOR:
310                 default:
311 
312                     return(NX_MSRP_ATTRIBUTE_TYPE_ERROR);
313                 }
314 
315                 if (difference < 0)
316                 {
317 
318                     (*attribute_ptr) -> next = msrp_attribute;
319 
320                     if (msrp_attribute == participant -> inused_head)
321                     {
322                         participant -> inused_head = *attribute_ptr;
323 
324                         break;
325                     }
326                     else
327                     {
328                         tmp -> next = *attribute_ptr;
329                     }
330                 }
331                 else
332                 {
333 
334                     tmp = msrp_attribute;
335                     msrp_attribute = msrp_attribute -> next;
336                     if (msrp_attribute == NX_NULL)
337                     {
338                         tmp -> next = *attribute_ptr;
339                         (*attribute_ptr) -> next = NX_NULL;
340                         return(NX_MSRP_ATTRIBUTE_NEW);
341                     }
342                 }
343             }
344         }
345         else
346         {
347 
348             (*attribute_ptr) -> next = msrp_attribute;
349 
350             if (msrp_attribute == participant -> inused_head)
351             {
352                 participant -> inused_head = *attribute_ptr;
353 
354                 break;
355             }
356             else
357             {
358                 tmp -> next = *attribute_ptr;
359 
360                 break;
361             }
362         }
363     }
364 
365     return(NX_MSRP_ATTRIBUTE_NEW);
366 }
367 
368 /**************************************************************************/
369 /*                                                                        */
370 /*  FUNCTION                                               RELEASE        */
371 /*                                                                        */
372 /*    nx_msrp_register_stream_request                     PORTABLE C      */
373 /*                                                           6.4.0        */
374 /*  AUTHOR                                                                */
375 /*                                                                        */
376 /*    Wen Wang,  Microsoft Corporation                                    */
377 /*                                                                        */
378 /*  DESCRIPTION                                                           */
379 /*                                                                        */
380 /*    This function register stream request.                              */
381 /*                                                                        */
382 /*  INPUT                                                                 */
383 /*                                                                        */
384 /*    mrp                                   MRP instance pointer          */
385 /*    participant                           MRP participant               */
386 /*    talker_advertise                      Talker advertise properties   */
387 /*    attribute_type                        Attribute type                */
388 /*    new_request                           Create new request            */
389 /*                                                                        */
390 /*  OUTPUT                                                                */
391 /*                                                                        */
392 /*    status                                Completion status             */
393 /*                                                                        */
394 /*  CALLS                                                                 */
395 /*                                                                        */
396 /*    nx_msrp_attribute_find                Find MSRP attribute           */
397 /*    nx_mrp_event_process                  Process mrp_event             */
398 /*                                                                        */
399 /*  CALLED BY                                                             */
400 /*                                                                        */
401 /*    nx_srp_talker_start                   Start SRP talker              */
402 /*                                                                        */
403 /*  RELEASE HISTORY                                                       */
404 /*                                                                        */
405 /*    DATE              NAME                      DESCRIPTION             */
406 /*                                                                        */
407 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
408 /*                                                                        */
409 /**************************************************************************/
nx_msrp_register_stream_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MSRP_TALKER_ADVERTISE * talker_advertise,UINT new_request)410 UINT nx_msrp_register_stream_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MSRP_TALKER_ADVERTISE *talker_advertise, UINT new_request)
411 {
412 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
413 UINT              status;
414 UCHAR            *attribute_value;
415 UCHAR             attribute_type;
416 UCHAR             mrp_event;
417 
418     if (new_request)
419     {
420 
421         mrp_event = NX_MRP_EVENT_NEW;
422     }
423     else
424     {
425 
426         mrp_event = NX_MRP_EVENT_JOIN;
427         return(NX_MSRP_EVENT_NOT_SUPPORTED);
428     }
429 
430     attribute_type = NX_MSRP_TALKER_ADVERTISE_VECTOR;
431 
432     attribute_value = talker_advertise -> stream_id;
433 
434     /* Get mrp mutex. */
435     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
436 
437     status = nx_msrp_attribute_find(mrp, participant,  &attribute, attribute_type, attribute_value);
438 
439     if (attribute != NX_NULL)
440     {
441 
442         attribute -> attribute_type = NX_MSRP_TALKER_ADVERTISE_VECTOR;
443 
444         memcpy(&(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise),
445                  talker_advertise, sizeof(NX_MSRP_TALKER_ADVERTISE)); /* use case of memcpy is verified. */
446 
447         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
448 
449         status = nx_mrp_event_process(mrp, participant, attribute, mrp_event);
450     }
451     else
452     {
453         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
454     }
455 
456     /* Release the mutex.  */
457     tx_mutex_put(&(mrp -> mrp_mutex));
458     return(status);
459 }
460 
461 /**************************************************************************/
462 /*                                                                        */
463 /*  FUNCTION                                               RELEASE        */
464 /*                                                                        */
465 /*    nx_msrp_register_attach_request                     PORTABLE C      */
466 /*                                                           6.4.0        */
467 /*  AUTHOR                                                                */
468 /*                                                                        */
469 /*    Wen Wang,  Microsoft Corporation                                    */
470 /*                                                                        */
471 /*  DESCRIPTION                                                           */
472 /*                                                                        */
473 /*    This function register stream attach request.                       */
474 /*                                                                        */
475 /*  INPUT                                                                 */
476 /*                                                                        */
477 /*    mrp                                   MRP instance pointer          */
478 /*    participant                           MRP participant               */
479 /*    stream_id                             Stream ID                     */
480 /*    fourpacked_value                      fourpacked value              */
481 /*                                                                        */
482 /*  OUTPUT                                                                */
483 /*                                                                        */
484 /*    status                                Completion status             */
485 /*                                                                        */
486 /*  CALLS                                                                 */
487 /*                                                                        */
488 /*    nx_msrp_attribute_find                Find MSRP attribute           */
489 /*    nx_mrp_event_process                  Process mrp_event             */
490 /*                                                                        */
491 /*  CALLED BY                                                             */
492 /*                                                                        */
493 /*    nx_msrp_register_stream_indication    Indication MSRP register      */
494 /*                                                                        */
495 /*  RELEASE HISTORY                                                       */
496 /*                                                                        */
497 /*    DATE              NAME                      DESCRIPTION             */
498 /*                                                                        */
499 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
500 /*                                                                        */
501 /**************************************************************************/
nx_msrp_register_attach_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,UCHAR * stream_id,UINT mrp_event,UCHAR fourpacked_value)502 UINT nx_msrp_register_attach_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, UCHAR *stream_id, UINT mrp_event, UCHAR fourpacked_value)
503 {
504 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
505 UINT              status;
506 UCHAR             attribute_type = NX_MSRP_TALKER_LISTENER_VECTOR;
507 
508     /* Get mutex. */
509     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
510 
511     status = nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, stream_id);
512 
513     if (attribute != NX_NULL)
514     {
515 
516         attribute -> attribute_type = NX_MSRP_TALKER_LISTENER_VECTOR;
517 
518         memcpy(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.stream_id,
519                 stream_id, 8); /* use case of memcpy is verified. */
520 
521         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
522 
523         ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event = fourpacked_value;
524 
525         status = nx_mrp_event_process(mrp, participant, attribute, (UCHAR)mrp_event);
526     }
527     else
528     {
529         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
530     }
531 
532     /* Release the mutex.  */
533     tx_mutex_put(&(mrp -> mrp_mutex));
534     return(status);
535 }
536 
537 /**************************************************************************/
538 /*                                                                        */
539 /*  FUNCTION                                               RELEASE        */
540 /*                                                                        */
541 /*    nx_msrp_deregister_stream_request                   PORTABLE C      */
542 /*                                                           6.4.0        */
543 /*  AUTHOR                                                                */
544 /*                                                                        */
545 /*    Wen Wang,  Microsoft Corporation                                    */
546 /*                                                                        */
547 /*  DESCRIPTION                                                           */
548 /*                                                                        */
549 /*    This function deregister stream request.                            */
550 /*                                                                        */
551 /*  INPUT                                                                 */
552 /*                                                                        */
553 /*    mrp                                   MRP instance pointer          */
554 /*    participant                           MRP participant               */
555 /*    stream_id                             Stream ID                     */
556 /*                                                                        */
557 /*  OUTPUT                                                                */
558 /*                                                                        */
559 /*    status                                Completion status             */
560 /*                                                                        */
561 /*  CALLS                                                                 */
562 /*                                                                        */
563 /*    nx_msrp_attribute_find                Find MSRP attribute           */
564 /*    nx_mrp_event_process                  Process mrp_event             */
565 /*                                                                        */
566 /*  CALLED BY                                                             */
567 /*                                                                        */
568 /*    nx_srp_talker_stop                    Stop SRP talker               */
569 /*                                                                        */
570 /*  RELEASE HISTORY                                                       */
571 /*                                                                        */
572 /*    DATE              NAME                      DESCRIPTION             */
573 /*                                                                        */
574 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
575 /*                                                                        */
576 /**************************************************************************/
nx_msrp_deregister_stream_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,UCHAR * stream_id)577 UINT nx_msrp_deregister_stream_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, UCHAR *stream_id)
578 {
579 UINT              status;
580 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
581 UINT              mrp_event = NX_MRP_EVENT_LV;
582 UCHAR             attribute_type = NX_MSRP_TALKER_ADVERTISE_VECTOR;
583 
584     /* Get mutex. */
585     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
586 
587     status = nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, stream_id);
588 
589     if (status == NX_MSRP_ATTRIBUTE_FOUND)
590     {
591         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
592 
593         status = nx_mrp_event_process(mrp, participant, attribute, (UCHAR)mrp_event);
594     }
595     else
596     {
597         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
598     }
599 
600     /* Release the mutex.  */
601     tx_mutex_put(&(mrp -> mrp_mutex));
602     return(status);
603 }
604 
605 /**************************************************************************/
606 /*                                                                        */
607 /*  FUNCTION                                               RELEASE        */
608 /*                                                                        */
609 /*    nx_msrp_deregister_attach_request                   PORTABLE C      */
610 /*                                                           6.4.0        */
611 /*  AUTHOR                                                                */
612 /*                                                                        */
613 /*    Wen Wang,  Microsoft Corporation                                    */
614 /*                                                                        */
615 /*  DESCRIPTION                                                           */
616 /*                                                                        */
617 /*    This function deregister stream attach request.                     */
618 /*                                                                        */
619 /*  INPUT                                                                 */
620 /*                                                                        */
621 /*    mrp                                   MRP instance pointer          */
622 /*    participant                           MRP participant               */
623 /*    stream_id                             Stream ID                     */
624 /*                                                                        */
625 /*  OUTPUT                                                                */
626 /*                                                                        */
627 /*    status                                Completion status             */
628 /*                                                                        */
629 /*  CALLS                                                                 */
630 /*                                                                        */
631 /*    nx_msrp_attribute_find                Find MSRP attribute           */
632 /*    nx_mrp_event_process                  Process MRP mrp_event         */
633 /*                                                                        */
634 /*  CALLED BY                                                             */
635 /*                                                                        */
636 /*    nx_msrp_deregister_stream_indication  receive deregister stream     */
637 /*    nx_srp_listener_stop                  Stop SRP listener             */
638 /*                                                                        */
639 /*  RELEASE HISTORY                                                       */
640 /*                                                                        */
641 /*    DATE              NAME                      DESCRIPTION             */
642 /*                                                                        */
643 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
644 /*                                                                        */
645 /**************************************************************************/
nx_msrp_deregister_attach_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,UCHAR * stream_id)646 UINT nx_msrp_deregister_attach_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, UCHAR *stream_id)
647 {
648 UINT              status;
649 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
650 UINT              mrp_event = NX_MRP_EVENT_LV;
651 UCHAR             attribute_type = NX_MSRP_TALKER_LISTENER_VECTOR;
652 
653     /* Get mrp mutex. */
654     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
655 
656     status = nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, stream_id);
657 
658     if (status == NX_MSRP_ATTRIBUTE_FOUND)
659     {
660 
661         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
662 
663         status = nx_mrp_event_process(mrp, participant, attribute, (UCHAR)mrp_event);
664     }
665     else
666     {
667         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
668     }
669 
670     /* Release the mutex.*/
671     tx_mutex_put(&(mrp -> mrp_mutex));
672     return(status);
673 }
674 
675 /**************************************************************************/
676 /*                                                                        */
677 /*  FUNCTION                                               RELEASE        */
678 /*                                                                        */
679 /*    nx_msrp_register_domain_request                     PORTABLE C      */
680 /*                                                           6.4.0        */
681 /*  AUTHOR                                                                */
682 /*                                                                        */
683 /*    Wen Wang,  Microsoft Corporation                                    */
684 /*                                                                        */
685 /*  DESCRIPTION                                                           */
686 /*                                                                        */
687 /*    This function register domain request.                              */
688 /*                                                                        */
689 /*  INPUT                                                                 */
690 /*                                                                        */
691 /*    mrp                                   MRP instance pointer          */
692 /*    participant                           MRP participant               */
693 /*    domain                                Stream properties             */
694 /*    new_request                           Create new request            */
695 /*                                                                        */
696 /*  OUTPUT                                                                */
697 /*                                                                        */
698 /*    status                                Completion status             */
699 /*                                                                        */
700 /*  CALLS                                                                 */
701 /*                                                                        */
702 /*    nx_msrp_attribute_find                Find MSRP attribute           */
703 /*    nx_mrp_event_process                  Process MRP mrp_event             */
704 /*                                                                        */
705 /*  CALLED BY                                                             */
706 /*                                                                        */
707 /*    nx_srp_talker_start                   Start SRP talker              */
708 /*                                                                        */
709 /*  RELEASE HISTORY                                                       */
710 /*                                                                        */
711 /*    DATE              NAME                      DESCRIPTION             */
712 /*                                                                        */
713 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
714 /*                                                                        */
715 /**************************************************************************/
nx_msrp_register_domain_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MSRP_DOMAIN * domain,UINT new_request)716 UINT nx_msrp_register_domain_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MSRP_DOMAIN *domain, UINT new_request)
717 {
718 
719 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
720 UINT              mrp_event;
721 UINT              status;
722 
723 
724     if (new_request)
725     {
726         mrp_event = NX_MRP_EVENT_NEW;
727     }
728     else
729     {
730         mrp_event = NX_MRP_EVENT_JOIN;
731         return(NX_MSRP_EVENT_NOT_SUPPORTED);
732     }
733 
734     /* Get mutex. */
735     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
736 
737     status = nx_msrp_attribute_find(mrp, participant, &attribute, NX_MSRP_TALKER_DOMAIN_VECTOR, &domain -> sr_class_id);
738 
739     if (attribute == NX_NULL)
740     {
741         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
742     }
743     else if (status == NX_MSRP_ATTRIBUTE_NEW)
744     {
745 
746         attribute -> attribute_type = NX_MSRP_TALKER_DOMAIN_VECTOR;
747 
748         memcpy(&(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain),
749                domain, sizeof(NX_MSRP_DOMAIN)); /* use case of memcpy is verified. */
750 
751         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
752 
753         status = nx_mrp_event_process(mrp, participant, attribute, (UCHAR)mrp_event);
754     }
755     else
756     {
757         status = NX_MSRP_SUCCESS;
758     }
759 
760     /* Release the mutex.  */
761     tx_mutex_put(&(mrp -> mrp_mutex));
762     return(status);
763 }
764 
765 /**************************************************************************/
766 /*                                                                        */
767 /*  FUNCTION                                               RELEASE        */
768 /*                                                                        */
769 /*    nx_msrp_deregister_domain_request                   PORTABLE C      */
770 /*                                                           6.4.0        */
771 /*  AUTHOR                                                                */
772 /*                                                                        */
773 /*    Wen Wang,  Microsoft Corporation                                    */
774 /*                                                                        */
775 /*  DESCRIPTION                                                           */
776 /*                                                                        */
777 /*    This function deregister domain request.                            */
778 /*                                                                        */
779 /*  INPUT                                                                 */
780 /*                                                                        */
781 /*    mrp                                   MRP instance pointer          */
782 /*    participant                           MRP participant               */
783 /*    domain                                Stream properties             */
784 /*                                                                        */
785 /*  OUTPUT                                                                */
786 /*                                                                        */
787 /*    status                                Completion status             */
788 /*                                                                        */
789 /*  CALLS                                                                 */
790 /*                                                                        */
791 /*    nx_msrp_attribute_find                Find MSRP attribute           */
792 /*    nx_mrp_event_process                  Process MRP mrp_event         */
793 /*                                                                        */
794 /*  CALLED BY                                                             */
795 /*                                                                        */
796 /*    nx_srp_talker_stop                    Stop SRP talker               */
797 /*    nx_srp_listener_stop                  Stop SRP listener             */
798 /*    nx_msrp_deregister_domain_indication  Deregister MSRP domain        */
799 /*                                          indication                    */
800 /*                                                                        */
801 /*  RELEASE HISTORY                                                       */
802 /*                                                                        */
803 /*    DATE              NAME                      DESCRIPTION             */
804 /*                                                                        */
805 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
806 /*                                                                        */
807 /**************************************************************************/
nx_msrp_deregister_domain_request(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MSRP_DOMAIN * domain)808 UINT nx_msrp_deregister_domain_request(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MSRP_DOMAIN *domain)
809 {
810 
811 NX_MRP_ATTRIBUTE *attribute = NX_NULL;
812 UINT              mrp_event = NX_MRP_EVENT_LV;
813 UINT              status;
814 
815     /* Get mutex. */
816     tx_mutex_get(&mrp -> mrp_mutex, NX_WAIT_FOREVER);
817 
818     status = nx_msrp_attribute_find(mrp, participant, &attribute, NX_MSRP_TALKER_DOMAIN_VECTOR, &domain -> sr_class_id);
819 
820     if (status == NX_MSRP_ATTRIBUTE_FOUND)
821     {
822 
823         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
824 
825         status = nx_mrp_event_process(mrp, participant, attribute, (UCHAR)mrp_event);
826     }
827     else
828     {
829         status = NX_MSRP_ATTRIBUTE_FIND_ERROR;
830     }
831 
832     /* Release the mutex.  */
833     tx_mutex_put(&(mrp -> mrp_mutex));
834     return(status);
835 }
836 
837 /**************************************************************************/
838 /*                                                                        */
839 /*  FUNCTION                                               RELEASE        */
840 /*                                                                        */
841 /*    nx_msrp_register_stream_indication                  PORTABLE C      */
842 /*                                                           6.4.0        */
843 /*  AUTHOR                                                                */
844 /*                                                                        */
845 /*    Wen Wang,  Microsoft Corporation                                    */
846 /*                                                                        */
847 /*  DESCRIPTION                                                           */
848 /*                                                                        */
849 /*    This function register stream indication.                           */
850 /*                                                                        */
851 /*  INPUT                                                                 */
852 /*                                                                        */
853 /*    mrp                                   MRP instance pointer          */
854 /*    participant                           MRP participant               */
855 /*    attribute                             Attribute                     */
856 /*    indication_type                       Indication type               */
857 /*                                                                        */
858 /*  OUTPUT                                                                */
859 /*                                                                        */
860 /*    status                                Completion status             */
861 /*                                                                        */
862 /*  CALLS                                                                 */
863 /*                                                                        */
864 /*    nx_msrp_register_attach_request       MSRP register attach request  */
865 /*    event_callback                        Application callback          */
866 /*                                                                        */
867 /*  CALLED BY                                                             */
868 /*                                                                        */
869 /*    nx_msrp_indication_process            Process MSRP indication       */
870 /*                                                                        */
871 /*  RELEASE HISTORY                                                       */
872 /*                                                                        */
873 /*    DATE              NAME                      DESCRIPTION             */
874 /*                                                                        */
875 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
876 /*                                                                        */
877 /**************************************************************************/
nx_msrp_register_stream_indication(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UINT indication_type)878 UINT nx_msrp_register_stream_indication(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UINT indication_type)
879 {
880 UINT                  status;
881 UCHAR                *stream_id;
882 NX_MRP_EVENT_CALLBACK event_callback;
883 
884 
885     if (((NX_MSRP *)participant) -> listener_enable)
886     {
887 
888         event_callback = ((NX_MSRP *)participant) -> msrp_event_callback;
889 
890 
891         if (event_callback != NX_NULL)
892         {
893 
894             status = event_callback(participant, attribute, (UCHAR)indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
895 
896             /* Listener receives register stream idication, then starts to register attach request*/
897             if (status == NX_MSRP_SUCCESS)
898             {
899 
900                 stream_id = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id;
901 
902                 status = nx_msrp_register_attach_request(mrp, participant, stream_id, indication_type, NX_MSRP_FOURPACKED_READY);
903             }
904         }
905         else
906         {
907             stream_id = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id;
908 
909             ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event = NX_MSRP_FOURPACKED_READY;
910 
911             status = nx_msrp_register_attach_request(mrp, participant, stream_id, indication_type, NX_MSRP_FOURPACKED_READY);
912         }
913     }
914     else
915     {
916 
917         return(NX_MSRP_LISTENER_NOT_ENABLED);
918     }
919 
920     return(status);
921 }
922 
923 /**************************************************************************/
924 /*                                                                        */
925 /*  FUNCTION                                               RELEASE        */
926 /*                                                                        */
927 /*    nx_msrp_deregister_stream_indication                PORTABLE C      */
928 /*                                                           6.4.0        */
929 /*  AUTHOR                                                                */
930 /*                                                                        */
931 /*    Wen Wang,  Microsoft Corporation                                    */
932 /*                                                                        */
933 /*  DESCRIPTION                                                           */
934 /*                                                                        */
935 /*    This function deregister stream indication.                         */
936 /*                                                                        */
937 /*  INPUT                                                                 */
938 /*                                                                        */
939 /*    mrp                                   MRP instance pointer          */
940 /*    participant                           MRP participant               */
941 /*    attribute                             Attribute                     */
942 /*    indication_type                       Indication type               */
943 /*                                                                        */
944 /*  OUTPUT                                                                */
945 /*                                                                        */
946 /*    status                                Completion status             */
947 /*                                                                        */
948 /*  CALLS                                                                 */
949 /*                                                                        */
950 /*    nx_msrp_deregister_attach_request     MSRP deregister attach request*/
951 /*    event_callback                        Application callback          */
952 /*                                                                        */
953 /*  CALLED BY                                                             */
954 /*                                                                        */
955 /*    nx_msrp_indication_process            Process MSRP indication       */
956 /*                                                                        */
957 /*  RELEASE HISTORY                                                       */
958 /*                                                                        */
959 /*    DATE              NAME                      DESCRIPTION             */
960 /*                                                                        */
961 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
962 /*                                                                        */
963 /**************************************************************************/
nx_msrp_deregister_stream_indication(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)964 UINT nx_msrp_deregister_stream_indication(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
965 {
966 
967 UINT                  status;
968 NX_MRP_EVENT_CALLBACK event_callback;
969 
970 event_callback             = ((NX_MSRP *)participant) -> msrp_event_callback;
971 UCHAR *stream_id;
972 
973     if (event_callback)
974     {
975 
976         status = event_callback(participant, attribute, indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
977 
978         if (status)
979         {
980             return(status);
981         }
982 
983         stream_id = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id;
984 
985         /*Listener Receive deregister indication, send deregister attach*/
986         nx_msrp_deregister_attach_request(mrp, participant, stream_id);
987     }
988 
989     return(status);
990 }
991 
992 /**************************************************************************/
993 /*                                                                        */
994 /*  FUNCTION                                               RELEASE        */
995 /*                                                                        */
996 /*    nx_msrp_register_attach_indication                  PORTABLE C      */
997 /*                                                           6.4.0        */
998 /*  AUTHOR                                                                */
999 /*                                                                        */
1000 /*    Wen Wang,  Microsoft Corporation                                    */
1001 /*                                                                        */
1002 /*  DESCRIPTION                                                           */
1003 /*                                                                        */
1004 /*    This function register attach indication.                           */
1005 /*                                                                        */
1006 /*  INPUT                                                                 */
1007 /*                                                                        */
1008 /*    participant                           MRP participant               */
1009 /*    attribute                             Attribute                     */
1010 /*    indication_type                       Indication type               */
1011 /*                                                                        */
1012 /*  OUTPUT                                                                */
1013 /*                                                                        */
1014 /*    status                                Completion status             */
1015 /*                                                                        */
1016 /*  CALLS                                                                 */
1017 /*                                                                        */
1018 /*    event_callback                        Application callback          */
1019 /*                                                                        */
1020 /*  CALLED BY                                                             */
1021 /*                                                                        */
1022 /*    nx_msrp_indication_process            Process MSRP indication       */
1023 /*                                                                        */
1024 /*  RELEASE HISTORY                                                       */
1025 /*                                                                        */
1026 /*    DATE              NAME                      DESCRIPTION             */
1027 /*                                                                        */
1028 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1029 /*                                                                        */
1030 /**************************************************************************/
nx_msrp_register_attach_indication(NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)1031 UINT nx_msrp_register_attach_indication(NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
1032 {
1033 UINT                  status = NX_MSRP_SUCCESS;
1034 NX_MRP_EVENT_CALLBACK event_callback;
1035 
1036     event_callback = ((NX_MSRP *)participant) -> msrp_event_callback;
1037 
1038     if (event_callback != NX_NULL)
1039     {
1040 
1041         status = event_callback(participant, attribute, indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
1042     }
1043 
1044     return(status);
1045 }
1046 
1047 /**************************************************************************/
1048 /*                                                                        */
1049 /*  FUNCTION                                               RELEASE        */
1050 /*                                                                        */
1051 /*    nx_msrp_deregister_attach_indication                PORTABLE C      */
1052 /*                                                           6.4.0        */
1053 /*  AUTHOR                                                                */
1054 /*                                                                        */
1055 /*    Wen Wang,  Microsoft Corporation                                    */
1056 /*                                                                        */
1057 /*  DESCRIPTION                                                           */
1058 /*                                                                        */
1059 /*    This function deregister attach indication.                         */
1060 /*                                                                        */
1061 /*  INPUT                                                                 */
1062 /*                                                                        */
1063 /*    participant                           MRP participant               */
1064 /*    attribute                             Attribute                     */
1065 /*    indication_type                       Indication type               */
1066 /*                                                                        */
1067 /*  OUTPUT                                                                */
1068 /*                                                                        */
1069 /*    status                                Completion status             */
1070 /*                                                                        */
1071 /*  CALLS                                                                 */
1072 /*                                                                        */
1073 /*    event_callback                        Application callback          */
1074 /*                                                                        */
1075 /*  CALLED BY                                                             */
1076 /*                                                                        */
1077 /*    nx_msrp_indication_process            Process MSRP indication       */
1078 /*                                                                        */
1079 /*  RELEASE HISTORY                                                       */
1080 /*                                                                        */
1081 /*    DATE              NAME                      DESCRIPTION             */
1082 /*                                                                        */
1083 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1084 /*                                                                        */
1085 /**************************************************************************/
nx_msrp_deregister_attach_indication(NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)1086 UINT nx_msrp_deregister_attach_indication(NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
1087 {
1088 UINT                  status = NX_MSRP_SUCCESS;
1089 NX_MRP_EVENT_CALLBACK event_callback;
1090 
1091     event_callback = ((NX_MSRP *)participant) -> msrp_event_callback;
1092 
1093     if (event_callback != NX_NULL)
1094     {
1095 
1096         status = event_callback(participant, attribute, indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
1097     }
1098 
1099     return(status);
1100 }
1101 
1102 /**************************************************************************/
1103 /*                                                                        */
1104 /*  FUNCTION                                               RELEASE        */
1105 /*                                                                        */
1106 /*    nx_msrp_register_domain_indication                  PORTABLE C      */
1107 /*                                                           6.4.0        */
1108 /*  AUTHOR                                                                */
1109 /*                                                                        */
1110 /*    Wen Wang,  Microsoft Corporation                                    */
1111 /*                                                                        */
1112 /*  DESCRIPTION                                                           */
1113 /*                                                                        */
1114 /*    This function register domain indication.                           */
1115 /*                                                                        */
1116 /*  INPUT                                                                 */
1117 /*                                                                        */
1118 /*    mrp                                   MRP instance pointer          */
1119 /*    participant                           MRP participant               */
1120 /*    attribute                             Attribute                     */
1121 /*    indication_type                       Indication type               */
1122 /*                                                                        */
1123 /*  OUTPUT                                                                */
1124 /*                                                                        */
1125 /*    status                                Completion status             */
1126 /*                                                                        */
1127 /*  CALLS                                                                 */
1128 /*                                                                        */
1129 /*    event_callback                        Application callback          */
1130 /*    nx_msrp_register_domain_request       MSRP register domain request  */
1131 /*                                                                        */
1132 /*  CALLED BY                                                             */
1133 /*                                                                        */
1134 /*    nx_msrp_indication_process            Process MSRP indication       */
1135 /*                                                                        */
1136 /*  RELEASE HISTORY                                                       */
1137 /*                                                                        */
1138 /*    DATE              NAME                      DESCRIPTION             */
1139 /*                                                                        */
1140 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1141 /*                                                                        */
1142 /**************************************************************************/
nx_msrp_register_domain_indication(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)1143 UINT nx_msrp_register_domain_indication(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
1144 {
1145 UINT                  status;
1146 NX_MRP_EVENT_CALLBACK event_callback;
1147 
1148 event_callback             = ((NX_MSRP *)participant) -> msrp_event_callback;
1149 NX_MSRP_DOMAIN *domain;
1150 
1151 
1152     if (event_callback != NX_NULL)
1153     {
1154         status = event_callback(participant, attribute, indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
1155 
1156         if (status != NX_MSRP_SUCCESS)
1157         {
1158             return(status);
1159         }
1160 
1161         domain = &(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain);
1162 
1163         nx_msrp_register_domain_request(mrp, participant, domain, NX_MSRP_ACTION_NEW);
1164     }
1165 
1166     return(status);
1167 }
1168 
1169 /**************************************************************************/
1170 /*                                                                        */
1171 /*  FUNCTION                                               RELEASE        */
1172 /*                                                                        */
1173 /*    nx_msrp_deregister_domain_indication                PORTABLE C      */
1174 /*                                                           6.4.0        */
1175 /*  AUTHOR                                                                */
1176 /*                                                                        */
1177 /*    Wen Wang,  Microsoft Corporation                                    */
1178 /*                                                                        */
1179 /*  DESCRIPTION                                                           */
1180 /*                                                                        */
1181 /*    This function deregister domain indication.                         */
1182 /*                                                                        */
1183 /*  INPUT                                                                 */
1184 /*                                                                        */
1185 /*    mrp                                   MRP instance pointer          */
1186 /*    participant                           MRP participant               */
1187 /*    attribute                             Attribute                     */
1188 /*    indication_type                       Indication type               */
1189 /*                                                                        */
1190 /*  OUTPUT                                                                */
1191 /*                                                                        */
1192 /*    status                                Completion status             */
1193 /*                                                                        */
1194 /*  CALLS                                                                 */
1195 /*                                                                        */
1196 /*    event_callback                        Application callback          */
1197 /*    nx_msrp_deregister_domain_request     MSRP deregister domain request*/
1198 /*                                                                        */
1199 /*  CALLED BY                                                             */
1200 /*                                                                        */
1201 /*    nx_msrp_indication_process            Process MSRP indication       */
1202 /*                                                                        */
1203 /*  RELEASE HISTORY                                                       */
1204 /*                                                                        */
1205 /*    DATE              NAME                      DESCRIPTION             */
1206 /*                                                                        */
1207 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1208 /*                                                                        */
1209 /**************************************************************************/
nx_msrp_deregister_domain_indication(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)1210 UINT nx_msrp_deregister_domain_indication(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
1211 {
1212 UINT                  status = NX_MSRP_SUCCESS;
1213 NX_MRP_EVENT_CALLBACK event_callback;
1214 
1215 event_callback             = ((NX_MSRP *)participant) -> msrp_event_callback;
1216 NX_MSRP_DOMAIN *domain;
1217 
1218     if (event_callback)
1219     {
1220         status = event_callback(participant, attribute, indication_type, ((NX_MSRP *)participant) -> msrp_callback_data);
1221 
1222         if (status != NX_MSRP_SUCCESS)
1223         {
1224             return(status);
1225         }
1226 
1227         domain = &(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain);
1228 
1229         nx_msrp_deregister_domain_request(mrp, participant, domain);
1230     }
1231 
1232     return(status);
1233 }
1234 
1235 /**************************************************************************/
1236 /*                                                                        */
1237 /*  FUNCTION                                               RELEASE        */
1238 /*                                                                        */
1239 /*    nx_msrp_indication_process                          PORTABLE C      */
1240 /*                                                           6.4.0        */
1241 /*  AUTHOR                                                                */
1242 /*                                                                        */
1243 /*    Wen Wang,  Microsoft Corporation                                    */
1244 /*                                                                        */
1245 /*  DESCRIPTION                                                           */
1246 /*                                                                        */
1247 /*    This function process MSRP indication.                              */
1248 /*                                                                        */
1249 /*  INPUT                                                                 */
1250 /*                                                                        */
1251 /*    mrp                                   MRP instance pointer          */
1252 /*    participant                           MRP participant               */
1253 /*    attribute                             Attribute                     */
1254 /*    indication_type                       Indication type               */
1255 /*                                                                        */
1256 /*  OUTPUT                                                                */
1257 /*                                                                        */
1258 /*    status                                Completion status             */
1259 /*                                                                        */
1260 /*  CALLS                                                                 */
1261 /*                                                                        */
1262 /*    nx_msrp_register_stream_indication    MSRP register stream indicate */
1263 /*    nx_msrp_deregister_stream_indication  MSRP deregister srteam        */
1264 /*                                          indicate                      */
1265 /*    nx_msrp_register_attach_indication    MSRP register attach indicate */
1266 /*    nx_msrp_deregister_attach_indication  MSRP deregister attach        */
1267 /*                                          indicate                      */
1268 /*    nx_msrp_register_domain_indication    MSRP register domain indicate */
1269 /*    nx_msrp_deregister_domain_indication  MSRP deregister domain        */
1270 /*                                          indicate                      */
1271 /*                                                                        */
1272 /*  CALLED BY                                                             */
1273 /*                                                                        */
1274 /*    nx_mrp_registrar_event_process        Process registrar mrp_event   */
1275 /*    nx_mrp_attribute_evict                Evict MRP attribute           */
1276 /*                                                                        */
1277 /*  RELEASE HISTORY                                                       */
1278 /*                                                                        */
1279 /*    DATE              NAME                      DESCRIPTION             */
1280 /*                                                                        */
1281 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1282 /*                                                                        */
1283 /**************************************************************************/
nx_msrp_indication_process(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,UCHAR indication_type)1284 UINT nx_msrp_indication_process(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type)
1285 {
1286 
1287 UINT status;
1288 
1289 
1290     switch (attribute -> attribute_type)
1291     {
1292     case NX_MSRP_TALKER_ADVERTISE_VECTOR:
1293 
1294         if (indication_type == NX_MRP_INDICATION_NEW || indication_type == NX_MRP_INDICATION_JOIN)
1295         {
1296             {
1297                 ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1298 
1299                 status = nx_msrp_register_stream_indication(mrp, participant, attribute, indication_type);
1300 
1301                 if (status != NX_MSRP_SUCCESS)
1302                 {
1303                     ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 0;
1304                 }
1305             }
1306         }
1307         else if (indication_type == NX_MRP_INDICATION_LV)
1308         {
1309             {
1310                 ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1311 
1312                 status = nx_msrp_deregister_stream_indication(mrp, participant, attribute, indication_type);
1313             }
1314         }
1315         else
1316         {
1317 
1318             status = NX_MSRP_INDICATION_TYPE_ERROR;
1319         }
1320 
1321         break;
1322 
1323     case NX_MSRP_TALKER_LISTENER_VECTOR:
1324 
1325         if (indication_type == NX_MRP_INDICATION_NEW || indication_type == NX_MRP_INDICATION_JOIN)
1326         {
1327             {
1328                 if (((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event >= NX_MSRP_FOURPACKED_READY)
1329                 {
1330                     status = nx_msrp_register_attach_indication(participant, attribute, indication_type);
1331 
1332                     ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1333                 }
1334             }
1335         }
1336         else if (indication_type == NX_MRP_INDICATION_LV)
1337         {
1338             {
1339 
1340                 if (((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event >= NX_MSRP_FOURPACKED_READY)
1341                 {
1342                     status = nx_msrp_deregister_attach_indication(participant, attribute, indication_type);
1343 
1344                     ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1345                 }
1346             }
1347         }
1348         else
1349         {
1350 
1351             status = NX_MSRP_INDICATION_TYPE_ERROR;
1352         }
1353 
1354         break;
1355 
1356     case NX_MSRP_TALKER_DOMAIN_VECTOR:
1357 
1358         if (indication_type == NX_MRP_INDICATION_NEW || indication_type == NX_MRP_INDICATION_JOIN)
1359         {
1360             {
1361                 ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1362 
1363                 status = nx_msrp_register_domain_indication(mrp, participant, attribute, indication_type);
1364             }
1365         }
1366         else if (indication_type == NX_MRP_INDICATION_LV)
1367         {
1368             {
1369                 ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1370 
1371                 status = nx_msrp_deregister_domain_indication(mrp, participant, attribute, indication_type);
1372             }
1373         }
1374         else
1375         {
1376             status = NX_MSRP_INDICATION_TYPE_ERROR;
1377         }
1378 
1379         break;
1380 
1381     case NX_MSRP_TALKER_FAILED_VECTOR:
1382 
1383         break;
1384 
1385     default:
1386 
1387         status = NX_MSRP_ATTRIBUTE_TYPE_ERROR;
1388         break;
1389     }
1390 
1391     return(status);
1392 }
1393 
1394 /**************************************************************************/
1395 /*                                                                        */
1396 /*  FUNCTION                                               RELEASE        */
1397 /*                                                                        */
1398 /*    nx_msrp_mrpdu_parse                                 PORTABLE C      */
1399 /*                                                           6.4.0        */
1400 /*  AUTHOR                                                                */
1401 /*                                                                        */
1402 /*    Wen Wang,  Microsoft Corporation                                    */
1403 /*                                                                        */
1404 /*  DESCRIPTION                                                           */
1405 /*                                                                        */
1406 /*    This function parse MRP data unit.                                  */
1407 /*                                                                        */
1408 /*  INPUT                                                                 */
1409 /*                                                                        */
1410 /*    mrp                                   MRP instance pointer          */
1411 /*    participant                           MRP participant               */
1412 /*    packet_ptr                            Packet pointer                */
1413 /*                                                                        */
1414 /*  OUTPUT                                                                */
1415 /*                                                                        */
1416 /*    status                                Completion status             */
1417 /*                                                                        */
1418 /*  CALLS                                                                 */
1419 /*                                                                        */
1420 /*    nx_msrp_attribute_find                MSRP attribute traverse       */
1421 /*    memcpy                                standard library              */
1422 /*                                                                        */
1423 /*                                                                        */
1424 /*  CALLED BY                                                             */
1425 /*                                                                        */
1426 /*    nx_mrp_registrar_event_process        Process registrar mrp_event   */
1427 /*    nx_mrp_attribute_evict                Evict MRP attribute           */
1428 /*                                                                        */
1429 /*  RELEASE HISTORY                                                       */
1430 /*                                                                        */
1431 /*    DATE              NAME                      DESCRIPTION             */
1432 /*                                                                        */
1433 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1434 /*                                                                        */
1435 /**************************************************************************/
nx_msrp_mrpdu_parse(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_PACKET * packet_ptr)1436 UINT nx_msrp_mrpdu_parse(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_PACKET *packet_ptr)
1437 {
1438 UINT                      status;
1439 NX_MRP_ATTRIBUTE         *attribute = NX_NULL;
1440 NX_MSRP_TALKER_ADVERTISE *talker_advertise_ptr;
1441 NX_MSRP_TALKER_FAILED    *talker_failed_ptr;
1442 UCHAR                     attribute_type;
1443 UINT                      attribute_type_index;
1444 UCHAR                     mrp_event;
1445 UCHAR                     is_end = 0;
1446 UINT                      attribute_list_length_index;
1447 USHORT                    num_of_value;
1448 UINT                      num_of_value_index;
1449 UINT                      first_value_index;
1450 UCHAR                     lva_event;
1451 UCHAR                     four_packed_event;
1452 UCHAR                     three_packed_event;
1453 USHORT                    attribute_list_length;
1454 UCHAR                     SRclass_id;
1455 UCHAR                    *stream_id;
1456 UCHAR                    *data_ptr = packet_ptr -> nx_packet_data_start;
1457 
1458 
1459 
1460     if (*(data_ptr + NX_MSRP_PROTOCAL_VERSION_INDEX) != 0)
1461     {
1462         return(NX_MSRP_VERSION_NOT_SUPPORTED);
1463     }
1464 
1465 
1466     attribute_type_index = NX_MSRP_PROTOCAL_VERSION_INDEX + 1;
1467 
1468 
1469     while (is_end == 0)
1470     {
1471 
1472         num_of_value_index = attribute_type_index + 4;
1473         attribute_list_length_index = attribute_type_index + 2;
1474 
1475         lva_event = *(data_ptr + num_of_value_index) >> 5;
1476         num_of_value = (USHORT)((*(data_ptr + num_of_value_index) & 0x1f) | *(data_ptr + num_of_value_index + 1));
1477 
1478         /*attribute header = 5 bytes*/
1479         first_value_index = attribute_type_index + 6;
1480 
1481         if (num_of_value > 1)
1482         {
1483 
1484             return(NX_MSRP_NOT_SUPPORTED);
1485         }
1486 
1487         attribute_type = *(data_ptr + attribute_type_index);
1488 
1489         attribute_list_length = (USHORT)(*(data_ptr + attribute_list_length_index) << 8 | *(data_ptr + attribute_list_length_index + 1));
1490 
1491 
1492         if (num_of_value)
1493         {
1494 
1495 
1496             switch (attribute_type)
1497             {
1498 
1499             case NX_MSRP_TALKER_ADVERTISE_VECTOR:
1500 
1501 
1502 
1503                 talker_advertise_ptr = (NX_MSRP_TALKER_ADVERTISE *)(data_ptr + first_value_index);
1504 
1505                 status = nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, talker_advertise_ptr -> stream_id);
1506 
1507                 /* No attribute was found or created.*/
1508                 if (attribute == NX_NULL)
1509                 {
1510 
1511                     return(NX_MSRP_ATTRIBUTE_FIND_ERROR);
1512                 }
1513 
1514                 if (status == NX_MSRP_ATTRIBUTE_NEW)
1515                 {
1516 
1517                     memcpy(&((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise, talker_advertise_ptr,
1518                            sizeof(NX_MSRP_TALKER_ADVERTISE)); /* use case of memcpy is verified. */
1519                 }
1520 
1521 
1522                 break;
1523 
1524             case NX_MSRP_TALKER_LISTENER_VECTOR:
1525 
1526                 stream_id = (data_ptr + first_value_index);
1527 
1528                 nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, stream_id);
1529 
1530                 /* No attribute was found or created.*/
1531                 if (attribute == NX_NULL)
1532                 {
1533 
1534                     return(NX_MSRP_ATTRIBUTE_FIND_ERROR);
1535                 }
1536 
1537                 if (status == NX_MSRP_ATTRIBUTE_NEW)
1538                 {
1539 
1540                     memcpy(&((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener, stream_id,
1541                            sizeof(NX_MSRP_LISTENER)); /* use case of memcpy is verified. */
1542                 }
1543 
1544                 four_packed_event = *(data_ptr + attribute_list_length_index + attribute_list_length - 1);
1545 
1546                 /* FourPackedEvents BYTE ::= ((FourPackedType *64) + (FourPackedType *16)+ (FourPackedType *4) + FourPackedType).*/
1547                 four_packed_event = four_packed_event / 64;
1548 
1549                 ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event = four_packed_event;
1550 
1551                 break;
1552 
1553             case NX_MSRP_TALKER_DOMAIN_VECTOR:
1554 
1555                 SRclass_id = *(data_ptr + first_value_index);
1556 
1557                 status = nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, &SRclass_id);
1558 
1559                 /* No attribute was found or created.*/
1560                 if (attribute == NX_NULL)
1561                 {
1562 
1563                     return(NX_MSRP_ATTRIBUTE_FIND_ERROR);
1564                 }
1565 
1566                 if (status == NX_MSRP_ATTRIBUTE_NEW)
1567                 {
1568                     /* If this is a exsit attribute, we assume that it comes from talker,*/
1569                     /* and if the applicaion did not start listener, send notify to user callback shouldn't happen.*/
1570                     if (((NX_MSRP *)participant) -> listener_enable == 0)
1571                     {
1572 
1573                         ((NX_MSRP_ATTRIBUTE *)attribute) -> indication_flag = 1;
1574                     }
1575 
1576                     memcpy(&((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain, (data_ptr + first_value_index),
1577                            sizeof(NX_MSRP_DOMAIN)); /* use case of memcpy is verified. */
1578 
1579                     NX_CHANGE_USHORT_ENDIAN(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_vid);
1580                 }
1581 
1582                 break;
1583 
1584             case NX_MSRP_TALKER_FAILED_VECTOR:
1585 
1586 
1587 
1588                 talker_failed_ptr = (NX_MSRP_TALKER_FAILED *)(data_ptr + first_value_index);
1589 
1590                 nx_msrp_attribute_find(mrp, participant, &attribute, attribute_type, talker_failed_ptr -> stream_id);
1591 
1592                 /* No attribute was found or created.*/
1593                 if (attribute == NX_NULL)
1594                 {
1595 
1596                     return(NX_MSRP_ATTRIBUTE_FIND_ERROR);
1597                 }
1598 
1599                 break;
1600 
1601             default:
1602 
1603                 return(NX_MSRP_ATTRIBUTE_TYPE_ERROR);
1604                 break;
1605             }
1606 
1607 
1608             if (lva_event)
1609             {
1610 
1611                 mrp_event = NX_MRP_EVENT_RLA;
1612 
1613                 nx_mrp_event_process(mrp, participant, attribute, mrp_event);
1614             }
1615 
1616             /* ThreePackedEvents BYTE ::= (((((AttributeEvent) *6) + AttributeEvent) *6) + AttributeEvent).*/
1617             three_packed_event = *(data_ptr + attribute_list_length_index + attribute_list_length - 2);
1618 
1619             three_packed_event = three_packed_event / 36;
1620 
1621             status = nx_mrp_event_process(mrp, participant, attribute, three_packed_event);
1622 
1623             if (status != NX_MSRP_SUCCESS)
1624             {
1625                 return(status);
1626             }
1627         }
1628 
1629         /* Endmask of each attribute *(data_ptr + attribute_list_length_index + attribute_list_length )*/
1630         /* Endmask of each attribute *(data_ptr + attribute_list_length_index + attribute_list_length + 1))*/
1631         if (*(data_ptr + attribute_list_length_index + attribute_list_length + 2) == NX_MSRP_ATTRIBUTE_END_MASK &&
1632             *(data_ptr + attribute_list_length_index + attribute_list_length + 3) == NX_MSRP_ATTRIBUTE_END_MASK)
1633         {
1634 
1635             is_end = 1;
1636         }
1637         else
1638         {
1639 
1640             /* 4bytes : attrubute length + attribute_list_length + 1*/
1641             attribute_type_index = attribute_type_index + attribute_list_length + 4;
1642         }
1643     }
1644 
1645     return(NX_MSRP_SUCCESS);
1646 }
1647 
1648 /**************************************************************************/
1649 /*                                                                        */
1650 /*  FUNCTION                                               RELEASE        */
1651 /*                                                                        */
1652 /*    nx_msrp_mrpdu_pack_attribute                        PORTABLE C      */
1653 /*                                                           6.4.0        */
1654 /*  AUTHOR                                                                */
1655 /*                                                                        */
1656 /*    Wen Wang,  Microsoft Corporation                                    */
1657 /*                                                                        */
1658 /*  DESCRIPTION                                                           */
1659 /*                                                                        */
1660 /*    This function pack attribute into MRP data unit.                    */
1661 /*                                                                        */
1662 /*  INPUT                                                                 */
1663 /*                                                                        */
1664 /*    participant                           MRP participant               */
1665 /*    attribute                             Attribute                     */
1666 /*    num_of_value                          Number of value               */
1667 /*    threepacked_event                     Threepacked mrp_event         */
1668 /*    fourpacked_event                      Fourpacked_event              */
1669 /*    data_ptr                              Data pointer                  */
1670 /*    length_ptr                            Length pointer                */
1671 /*                                                                        */
1672 /*  OUTPUT                                                                */
1673 /*                                                                        */
1674 /*    status                                Completion status             */
1675 /*                                                                        */
1676 /*  CALLS                                                                 */
1677 /*                                                                        */
1678 /*    memcpy                                standard library              */
1679 /*                                                                        */
1680 /*                                                                        */
1681 /*  CALLED BY                                                             */
1682 /*                                                                        */
1683 /*    nx_msrp_mrpdu_pack                    MSRP pack MRP data unit       */
1684 /*                                                                        */
1685 /*  RELEASE HISTORY                                                       */
1686 /*                                                                        */
1687 /*    DATE              NAME                      DESCRIPTION             */
1688 /*                                                                        */
1689 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1690 /*                                                                        */
1691 /**************************************************************************/
nx_msrp_mrpdu_pack_attribute(NX_MRP_PARTICIPANT * participant,NX_MRP_ATTRIBUTE * attribute,USHORT num_of_value,UCHAR * threepacked_event,UCHAR * fourpacked_event,UCHAR * data_ptr,UINT * length_ptr)1692 UINT nx_msrp_mrpdu_pack_attribute(NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, USHORT num_of_value,
1693                                   UCHAR *threepacked_event, UCHAR *fourpacked_event, UCHAR *data_ptr, UINT *length_ptr)
1694 {
1695 
1696 UCHAR  threepacked_value[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE  / 4 / 3 + 1];
1697 UCHAR  fourpacked_value[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE  / 4 / 3 + 1];
1698 UINT   num_of_threepacked;
1699 UINT   num_of_fourpacked;
1700 UINT   i, index = 0;
1701 UINT   lva_event = 0;
1702 USHORT tmp;
1703 USHORT attribute_list_length;
1704 
1705     /* Allowed max value of talker and listener.*/
1706     if (num_of_value > NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE  / 4)
1707     {
1708 
1709         return(NX_MSRP_PARAMETER_ERROR);
1710     }
1711 
1712     if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
1713     {
1714 
1715         lva_event = 1;
1716 
1717         /* Send only lva mrp_event, the attribute content will be null.*/
1718         if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_S_OPT))
1719         {
1720 
1721             num_of_value = 0;
1722 
1723             switch (attribute -> attribute_type)
1724             {
1725 
1726             case NX_MSRP_TALKER_ADVERTISE_VECTOR:
1727 
1728                 *data_ptr++ = NX_MSRP_TALKER_ADVERTISE_VECTOR;
1729                 *data_ptr++ = NX_MSRP_TALKER_ADVERTISE_ATTRIBUTE_LENGTH;
1730                 *data_ptr++ = 0;
1731 
1732                 /* 4 = vectorhead + endmark.*/
1733                 attribute_list_length = NX_MSRP_TALKER_ADVERTISE_ATTRIBUTE_LENGTH + 4;
1734                 *data_ptr++ = (UCHAR)attribute_list_length;
1735                 tmp = (USHORT)(lva_event << 13 | num_of_value);
1736                 *data_ptr++ = (UCHAR)(tmp >> 8);
1737                 *data_ptr++ = (UCHAR)tmp;
1738                 memset(data_ptr, 00, attribute_list_length);
1739                 /* 4 = attribute_type + attribute_length_attribute_list_length.*/
1740                 *length_ptr = (UINT)(attribute_list_length + 4);
1741 
1742                 break;
1743 
1744             case NX_MSRP_TALKER_LISTENER_VECTOR:
1745 
1746                 *data_ptr++ = NX_MSRP_TALKER_LISTENER_VECTOR;
1747                 *data_ptr++ = NX_MSRP_LISTENER_ATTRIBUTE_LENGTH;
1748                 *data_ptr++ = 0;
1749                 attribute_list_length = NX_MSRP_LISTENER_ATTRIBUTE_LENGTH + 4;
1750                 *data_ptr++ = (UCHAR)attribute_list_length;
1751                 tmp = (USHORT)(lva_event << 13 | num_of_value);
1752                 *data_ptr++ = (UCHAR)(tmp >> 8);
1753                 *data_ptr++ = (UCHAR)tmp;
1754                 memset(data_ptr, 00, attribute_list_length);
1755                 *length_ptr = (UINT)(attribute_list_length + 4);     // 4 = attribute_type + attribute_length_attribute_list_length
1756                 break;
1757 
1758             case NX_MSRP_TALKER_DOMAIN_VECTOR:
1759 
1760                 *data_ptr++ = NX_MSRP_TALKER_DOMAIN_VECTOR;
1761                 *data_ptr++ = NX_MSRP_DOMAIN_ATTRIBUTE_LENGTH;
1762                 *data_ptr++ = 0;
1763                 attribute_list_length = NX_MSRP_DOMAIN_ATTRIBUTE_LENGTH + 4;
1764                 *data_ptr++ = (UCHAR)attribute_list_length;
1765                 tmp = (USHORT)(lva_event << 13 | num_of_value);
1766                 *data_ptr++ = (UCHAR)(tmp >> 8);
1767                 *data_ptr++ = (UCHAR)tmp;
1768                 memset(data_ptr, 00, attribute_list_length);
1769                 *length_ptr = (UINT)(attribute_list_length + 4);     // 4 = attribute_type + attribute_length_attribute_list_length
1770 
1771                 break;
1772             case NX_MSRP_TALKER_FAILED_VECTOR:
1773             default:
1774                 break;
1775             }
1776 
1777             return(NX_MSRP_SUCCESS);
1778         }
1779     }
1780 
1781     /* Fill packet content next.*/
1782     if (num_of_value % 3)
1783     {
1784         num_of_threepacked = (UINT)(num_of_value / 3 + 1);
1785 
1786         num_of_fourpacked = (UINT)(num_of_value / 3 + 1);
1787     }
1788     else
1789     {
1790 
1791         num_of_threepacked = (UINT)(num_of_value / 3);
1792 
1793         num_of_fourpacked = (UINT)(num_of_value / 4);
1794     }
1795 
1796     /*ThreePackedEvents BYTE ::= (((((AttributeEvent) *6) + AttributeEvent) *6) + AttributeEvent)*/
1797     for (i = 0; i < num_of_threepacked; i++)
1798     {
1799 
1800         threepacked_value[i++] = (UCHAR)(((((threepacked_event[index]) * 6) + threepacked_event[index + 1]) * 6) + threepacked_event[index + 2]);
1801 
1802         index += 3;
1803     }
1804 
1805     switch (attribute -> attribute_type)
1806     {
1807 
1808     case NX_MSRP_TALKER_ADVERTISE_VECTOR:
1809 
1810         *data_ptr++ = NX_MSRP_TALKER_ADVERTISE_VECTOR;
1811         *data_ptr++ = NX_MSRP_TALKER_ADVERTISE_ATTRIBUTE_LENGTH;
1812         *data_ptr++ = 0;
1813 
1814         /* 4 = vectorhead + endmark*/
1815         attribute_list_length = (USHORT)(NX_MSRP_TALKER_ADVERTISE_ATTRIBUTE_LENGTH + 4 + num_of_threepacked);
1816         *data_ptr++ = (UCHAR)attribute_list_length;
1817         tmp = (USHORT)(lva_event << 13 | num_of_value);
1818         *data_ptr++ = (UCHAR)(tmp >> 8);
1819         *data_ptr++ = (UCHAR)tmp;
1820 
1821         memcpy(data_ptr,  ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id,
1822                sizeof(NX_MSRP_TALKER_ADVERTISE)); /* use case of memcpy is verified. */
1823 
1824         /* Fix the above copy endian 14 = stream_id + dest_addr*/
1825         *(data_ptr + 14) = (UCHAR)(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.vlan_identifier >> 8);
1826 
1827         *(data_ptr + 15) = (UCHAR)(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.vlan_identifier);
1828 
1829         for (i = 0; i < num_of_threepacked; i++)
1830         {
1831             *(data_ptr + sizeof(NX_MSRP_TALKER_ADVERTISE) + i) = threepacked_value[i];
1832         }
1833 
1834         /* Endmark*/
1835         (*(data_ptr + sizeof(NX_MSRP_TALKER_ADVERTISE) + num_of_threepacked)) = 0;
1836 
1837         (*(data_ptr + sizeof(NX_MSRP_TALKER_ADVERTISE) + num_of_threepacked + 1)) = 0;
1838 
1839         *length_ptr = (UINT)(attribute_list_length + 4);
1840 
1841         break;
1842 
1843     case NX_MSRP_TALKER_LISTENER_VECTOR:
1844 
1845         index = 0;
1846 
1847         /* FourPackedEvents BYTE ::= ((FourPackedType *64) + (FourPackedType *16)+ (FourPackedType *4) + FourPackedType)*/
1848         for (i = 0; i < num_of_fourpacked; i++)
1849         {
1850 
1851             fourpacked_value[i++] = (UCHAR)((fourpacked_event[index] * 64) + (fourpacked_event[index + 1] * 16) +
1852                                             (fourpacked_event[index + 2] * 4) + fourpacked_event[index + 3]);
1853 
1854             index += 4;
1855         }
1856         *data_ptr++ = NX_MSRP_TALKER_LISTENER_VECTOR;
1857         *data_ptr++ = NX_MSRP_LISTENER_ATTRIBUTE_LENGTH;
1858         *data_ptr++ = 0;
1859         attribute_list_length = (USHORT)(NX_MSRP_LISTENER_ATTRIBUTE_LENGTH + 4 + num_of_threepacked + num_of_fourpacked);
1860         *data_ptr++ = (UCHAR)attribute_list_length;
1861         tmp = (USHORT)(lva_event << 13 | num_of_value);
1862         *data_ptr++ = (UCHAR)(tmp >> 8);
1863         *data_ptr++ = (UCHAR)tmp;
1864 
1865         memcpy(data_ptr, ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.stream_id,
1866                STREAM_ID_SIZE); /* use case of memcpy is verified. */
1867 
1868         for (i = 0; i < num_of_threepacked; i++)
1869         {
1870             *(data_ptr + STREAM_ID_SIZE + i) = threepacked_value[i];
1871         }
1872 
1873         for (i = 0; i < num_of_fourpacked; i++)
1874         {
1875             *(data_ptr + STREAM_ID_SIZE + num_of_threepacked  + i) = fourpacked_value[i];
1876         }
1877 
1878         /* Endmark*/
1879         (*(data_ptr + STREAM_ID_SIZE + num_of_threepacked + num_of_fourpacked)) = 0;
1880 
1881         (*(data_ptr + STREAM_ID_SIZE + num_of_threepacked + num_of_fourpacked + 1)) = 0;
1882 
1883         /* 4 = attribute_type + attribute_length_attribute_list_length*/
1884         *length_ptr = (UINT)(attribute_list_length + 4);
1885 
1886         break;
1887 
1888     case NX_MSRP_TALKER_DOMAIN_VECTOR:
1889 
1890         *data_ptr++ = NX_MSRP_TALKER_DOMAIN_VECTOR;
1891         *data_ptr++ = NX_MSRP_DOMAIN_ATTRIBUTE_LENGTH;
1892         *data_ptr++ = 0;
1893         attribute_list_length = (USHORT)(NX_MSRP_DOMAIN_ATTRIBUTE_LENGTH + 4 + num_of_threepacked);
1894         *data_ptr++ = (UCHAR)attribute_list_length;
1895         tmp = (USHORT)((lva_event) << 13 | num_of_value);
1896         *data_ptr++ = (UCHAR)(tmp >> 8);
1897         *data_ptr++ = (UCHAR)tmp;
1898 
1899         *data_ptr = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_id;
1900         *(data_ptr + 1) = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_priority;
1901         *(data_ptr + 2) = (UCHAR)(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_vid >> 8);
1902         *(data_ptr + 3) = (UCHAR)(((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_vid);
1903 
1904         for (i = 0; i < num_of_threepacked; i++)
1905         {
1906             *(data_ptr + sizeof(NX_MSRP_DOMAIN) + i) = threepacked_value[i];
1907         }
1908 
1909         /* Endmark*/
1910         (*(data_ptr + sizeof(NX_MSRP_DOMAIN) + num_of_threepacked)) = 0;
1911         (*(data_ptr + sizeof(NX_MSRP_DOMAIN) + num_of_threepacked + 1)) = 0;
1912 
1913         /* 4 = attribute_type + attribute_length_attribute_list_length*/
1914         *length_ptr = (UINT)(attribute_list_length + 4);
1915 
1916         break;
1917 
1918     case NX_MSRP_TALKER_FAILED_VECTOR:
1919     default:
1920 
1921         return(NX_MSRP_ATTRIBUTE_TYPE_ERROR);
1922         break;
1923     }
1924 
1925     return(NX_MSRP_SUCCESS);
1926 }
1927 
1928 /**************************************************************************/
1929 /*                                                                        */
1930 /*  FUNCTION                                               RELEASE        */
1931 /*                                                                        */
1932 /*    nx_msrp_mrpdu_pack                                  PORTABLE C      */
1933 /*                                                           6.4.0        */
1934 /*  AUTHOR                                                                */
1935 /*                                                                        */
1936 /*    Wen Wang,  Microsoft Corporation                                    */
1937 /*                                                                        */
1938 /*  DESCRIPTION                                                           */
1939 /*                                                                        */
1940 /*    This function pack MRP data unit.                                   */
1941 /*                                                                        */
1942 /*  INPUT                                                                 */
1943 /*                                                                        */
1944 /*    mrp                                   MRP instance pointer          */
1945 /*    participant                           MRP participant               */
1946 /*    packet_ptr                            Packet pointer                */
1947 /*                                                                        */
1948 /*  OUTPUT                                                                */
1949 /*                                                                        */
1950 /*    status                                Completion status             */
1951 /*                                                                        */
1952 /*  CALLS                                                                 */
1953 /*                                                                        */
1954 /*    nx_packet_data_append                 Append data into packet       */
1955 /*    nx_msrp_mrpdu_pack_attribute          Pack MSRP attribute           */
1956 /*    nx_mrp_attribute_event_get            Get MRP attribute mrp_event   */
1957 /*                                                                        */
1958 /*                                                                        */
1959 /*  CALLED BY                                                             */
1960 /*                                                                        */
1961 /*    nx_mrp_join_timeout_process           MRP join timer timeout process*/
1962 /*                                                                        */
1963 /*  RELEASE HISTORY                                                       */
1964 /*                                                                        */
1965 /*    DATE              NAME                      DESCRIPTION             */
1966 /*                                                                        */
1967 /*  12-31-2023        Wen Wang              Initial Version 6.4.0         */
1968 /*                                                                        */
1969 /**************************************************************************/
nx_msrp_mrpdu_pack(NX_MRP * mrp,NX_MRP_PARTICIPANT * participant,NX_PACKET * packet_ptr)1970 UINT nx_msrp_mrpdu_pack(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_PACKET *packet_ptr)
1971 {
1972 
1973 UCHAR            *data_ptr = packet_ptr -> nx_packet_prepend_ptr;
1974 UINT              data_length = 0;
1975 UINT              status;
1976 NX_MRP_ATTRIBUTE *attribute = participant -> inused_head;
1977 NX_MRP_ATTRIBUTE *attribute_start;
1978 UCHAR            *id[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE];
1979 UCHAR             threepacked_event[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE];
1980 UCHAR             fourpacked_event[NX_MSRP_ATTRIBUTE_ARRAY_MAX_SIZE];
1981 UCHAR             index = 0;
1982 USHORT            num_of_value = 0;
1983 
1984     if (attribute -> attribute_type == 0)
1985     {
1986         return(NX_MSRP_ATTRIBUTE_TYPE_ERROR);
1987     }
1988 
1989     memset(threepacked_event, 0, sizeof(threepacked_event));
1990 
1991     *data_ptr = NX_MRP_MSRP_PROTOCOL_VERSION;
1992 
1993     data_length = 1;
1994 
1995     status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
1996 
1997     if (status)
1998     {
1999         return(status);
2000     }
2001 
2002     data_ptr++;
2003 
2004     /*Look up talkeradvertise attribute to pack*/
2005     while (attribute &&  attribute -> attribute_type == NX_MSRP_TALKER_ADVERTISE_VECTOR)
2006     {
2007 
2008         if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_S_OPT))
2009         {
2010             /* If lva action is needed, send lva attribute anyway.*/
2011             if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2012             {
2013 
2014                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2015 
2016                 if (status)
2017                 {
2018                     return(status);
2019                 }
2020 
2021                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2022 
2023                 if (status)
2024                 {
2025                     return(status);
2026                 }
2027 
2028                 data_ptr = data_ptr + data_length;
2029             }
2030 
2031             attribute = attribute -> next;
2032 
2033             continue;
2034         }
2035 
2036         attribute_start = attribute;
2037 
2038         nx_mrp_attribute_event_get(attribute, &threepacked_event[0]);
2039 
2040         id[0] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id;
2041 
2042 
2043         num_of_value = 1;
2044         index = 1;
2045 
2046 
2047         if (attribute -> next == NX_NULL || attribute -> next -> attribute_type != NX_MSRP_TALKER_ADVERTISE_VECTOR)
2048         {
2049 
2050             status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2051 
2052             if (status)
2053             {
2054                 return(status);
2055             }
2056 
2057             status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2058 
2059             if (status)
2060             {
2061                 return(status);
2062             }
2063 
2064             data_ptr = data_ptr + data_length;
2065 
2066             attribute = attribute -> next;
2067 
2068             break;
2069         }
2070 
2071         /* Continue looking up talkeradvertise attribute to pack.*/
2072         while ((attribute = attribute -> next)  && (attribute -> attribute_type == NX_MSRP_TALKER_ADVERTISE_VECTOR))
2073         {
2074 
2075             if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_SLA))
2076             {
2077                 /* If lva action is needed, send lva attribute anyway.*/
2078                 if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2079                 {
2080                     /* Need to check the paramter attribute_start or attribute*/
2081                     status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2082 
2083                     if (status)
2084                     {
2085                         return(status);
2086                     }
2087 
2088                     status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2089 
2090                     if (status)
2091                     {
2092                         return(status);
2093                     }
2094 
2095                     data_ptr = data_ptr + data_length;
2096                 }
2097 
2098                 continue;
2099             }
2100 
2101             id[index] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.talker_advertise.stream_id;
2102 
2103             nx_mrp_attribute_event_get(attribute, &threepacked_event[index]);
2104 
2105             if (memcmp(id[index], id[index - 1], 8) == 1)
2106             {
2107 
2108                 num_of_value++;
2109                 index++;
2110 
2111                 continue;
2112             }
2113             else
2114             {
2115 
2116                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2117 
2118                 if (status)
2119                 {
2120                     return(status);
2121                 }
2122 
2123                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2124 
2125                 if (status)
2126                 {
2127                     return(status);
2128                 }
2129 
2130                 data_ptr = data_ptr + data_length;
2131 
2132 
2133                 break;
2134             }
2135         }
2136     }
2137 
2138     /*Look up listener attribute to pack*/
2139     while (attribute && attribute -> attribute_type == NX_MSRP_TALKER_LISTENER_VECTOR)
2140     {
2141 
2142         if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_SLA))
2143         {
2144             /* If lva action is needed, send lva attribute anyway.*/
2145             if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2146             {
2147 
2148                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2149 
2150                 if (status)
2151                 {
2152                     return(status);
2153                 }
2154 
2155                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2156 
2157                 if (status)
2158                 {
2159                     return(status);
2160                 }
2161 
2162                 data_ptr = data_ptr + data_length;
2163             }
2164 
2165             attribute = attribute -> next;
2166 
2167             continue;
2168         }
2169 
2170         attribute_start = attribute;
2171 
2172         nx_mrp_attribute_event_get(attribute, &threepacked_event[0]);
2173 
2174         fourpacked_event[0] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event;
2175 
2176         id[0] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.stream_id;
2177 
2178         num_of_value = 1;
2179 
2180         index = 1;
2181 
2182         if (attribute -> next == NX_NULL || attribute -> next -> attribute_type != NX_MSRP_TALKER_LISTENER_VECTOR)
2183         {
2184 
2185             status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2186 
2187             if (status)
2188             {
2189                 return(status);
2190             }
2191 
2192             status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2193 
2194             if (status)
2195             {
2196                 return(status);
2197             }
2198 
2199             data_ptr = data_ptr + data_length;
2200 
2201             attribute = attribute -> next;
2202 
2203             break;
2204         }
2205         /* Continue looking up listener attribute to pack.*/
2206         while ((attribute = attribute -> next)  && (attribute -> attribute_type == NX_MSRP_TALKER_LISTENER_VECTOR))
2207         {
2208 
2209             if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_SLA))
2210             {
2211 
2212                 /* If lva action is needed, send lva attribute anyway.*/
2213                 if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2214                 {
2215 
2216                     status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2217 
2218                     if (status)
2219                     {
2220                         return(status);
2221                     }
2222 
2223                     status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2224 
2225                     if (status)
2226                     {
2227                         return(status);
2228                     }
2229 
2230                     data_ptr = data_ptr + data_length;
2231                 }
2232                 continue;
2233             }
2234 
2235             id[index] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.stream_id;
2236 
2237             fourpacked_event[index] = ((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.listener.fourpacked_event;
2238 
2239             nx_mrp_attribute_event_get(attribute, &threepacked_event[index]);
2240 
2241             if (memcmp(id[index], id[index - 1], 8) == 1)
2242             {
2243 
2244                 num_of_value++;
2245                 index++;
2246 
2247                 continue;
2248             }
2249             else
2250             {
2251 
2252                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2253 
2254                 if (status)
2255                 {
2256                     return(status);
2257                 }
2258 
2259                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2260 
2261                 if (status)
2262                 {
2263                     return(status);
2264                 }
2265 
2266                 data_ptr = data_ptr + data_length;
2267 
2268                 break;
2269             }
2270         }
2271     }
2272 
2273     /*Look up domain attribute to pack*/
2274     while (attribute && attribute -> attribute_type == NX_MSRP_TALKER_DOMAIN_VECTOR)
2275     {
2276 
2277         if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_SLA))
2278         {
2279             /* If lva action is needed, send lva attribute anyway.*/
2280             if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2281             {
2282 
2283                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2284 
2285                 if (status)
2286                 {
2287                     return(status);
2288                 }
2289 
2290                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2291 
2292                 if (status)
2293                 {
2294                     return(status);
2295                 }
2296 
2297                 data_ptr = data_ptr + data_length;
2298             }
2299 
2300             attribute = attribute -> next;
2301 
2302             continue;
2303         }
2304 
2305         attribute_start = attribute;
2306 
2307         nx_mrp_attribute_event_get(attribute, &threepacked_event[0]);
2308 
2309         id[0] = &((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_id;
2310 
2311         num_of_value = 1;
2312         index = 1;
2313 
2314         if (attribute -> next == NX_NULL)
2315         {
2316 
2317             status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2318 
2319             if (status)
2320             {
2321                 return(status);
2322             }
2323 
2324             status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2325 
2326             if (status)
2327             {
2328                 return(status);
2329             }
2330 
2331             data_ptr = data_ptr + data_length;
2332 
2333             attribute = attribute -> next;
2334 
2335             break;
2336         }
2337         /* Continue looking up domain attribute to pack.*/
2338         while ((attribute = attribute -> next)  && (attribute -> attribute_type == NX_MSRP_TALKER_DOMAIN_VECTOR))
2339         {
2340 
2341             if ((attribute -> applicant.action == NX_MRP_ACTION_NULL) || (attribute -> applicant.action > NX_MRP_ACTION_SLA))
2342             {
2343                 /* If lva action is needed, send lva attribute anyway.*/
2344                 if (participant -> leaveall.action == NX_MRP_ACTION_SLA)
2345                 {
2346 
2347                     status = nx_msrp_mrpdu_pack_attribute(participant, attribute, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2348 
2349                     if (status)
2350                     {
2351                         return(status);
2352                     }
2353 
2354                     status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2355 
2356                     if (status)
2357                     {
2358                         return(status);
2359                     }
2360 
2361                     data_ptr = data_ptr + data_length;
2362                 }
2363 
2364                 continue;
2365             }
2366 
2367             id[index] = &((NX_MSRP_ATTRIBUTE *)attribute) -> msrp_attribute_union.domain.sr_class_id;
2368 
2369             nx_mrp_attribute_event_get(attribute, &threepacked_event[index]);
2370 
2371             if (memcmp(id[index], id[index - 1], 1) == 1)
2372             {
2373 
2374                 num_of_value++;
2375                 index++;
2376 
2377                 continue;
2378             }
2379             else
2380             {
2381 
2382                 status = nx_msrp_mrpdu_pack_attribute(participant, attribute_start, num_of_value, threepacked_event, fourpacked_event, data_ptr, &data_length);
2383 
2384                 if (status)
2385                 {
2386                     return(status);
2387                 }
2388 
2389                 status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2390 
2391                 if (status)
2392                 {
2393                     return(status);
2394                 }
2395 
2396                 data_ptr = data_ptr + data_length;
2397 
2398                 break;
2399             }
2400         }
2401     }
2402 
2403     /* No attribute needs to be send.*/
2404     if (packet_ptr -> nx_packet_length == 1)
2405     {
2406         packet_ptr -> nx_packet_length = 0;
2407 
2408         return NX_MSRP_WAIT;
2409     }
2410     else
2411     {
2412         /* Add endmark*/
2413         *data_ptr = 0;
2414         *(data_ptr + 1) = 0;
2415 
2416         data_length = 2;
2417 
2418         status = nx_packet_data_append(packet_ptr, data_ptr, data_length, mrp -> pkt_pool, NX_NO_WAIT);
2419 
2420         if (status)
2421         {
2422             return(status);
2423         }
2424     }
2425 
2426     return(status);
2427 }
2428 #endif /* NX_ENABLE_VLAN */
2429 
2430