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 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   Real Time Streaming Protocol (RTSP)                                 */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 #define NX_RTSP_SERVER_SOURCE_CODE
22 
23 /* Force error checking to be disabled in this module.  */
24 
25 #ifndef NX_DISABLE_ERROR_CHECKING
26 #define NX_DISABLE_ERROR_CHECKING
27 #endif
28 
29 /* Include necessary system files.  */
30 
31 #include    "tx_api.h"
32 #include    "nx_api.h"
33 #include    "nx_ip.h"
34 #ifdef FEATURE_NX_IPV6
35 #include    "nx_ipv6.h"
36 #endif /* #ifdef FEATURE_NX_IPV6 */
37 #include    "nx_rtsp_server.h"
38 
39 /* Define the internal functions.  */
40 
41 static VOID _nx_rtsp_server_thread_entry(ULONG);
42 
43 static VOID _nx_rtsp_server_connect_present(NX_TCP_SOCKET *request_socket_ptr, UINT port);
44 static VOID _nx_rtsp_server_connect_process(NX_RTSP_SERVER *rtsp_server_ptr);
45 
46 static VOID _nx_rtsp_server_disconnect_present(NX_TCP_SOCKET *request_socket_ptr);
47 static VOID _nx_rtsp_server_disconnect_process(NX_RTSP_SERVER *rtsp_server_ptr);
48 
49 static VOID _nx_rtsp_server_request_present(NX_TCP_SOCKET *request_socket_ptr);
50 static VOID _nx_rtsp_server_request_process(NX_RTSP_SERVER *rtsp_server_ptr);
51 
52 static VOID _nx_rtsp_server_timeout(ULONG rtsp_server_address);
53 static VOID _nx_rtsp_server_timeout_process(NX_RTSP_SERVER *rtsp_server_ptr);
54 
55 static UINT _nx_rtsp_server_request_receive(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr);
56 static UINT _nx_rtsp_server_request_parse(NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr);
57 static UINT _nx_rtsp_server_request_line_parse(NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr, UCHAR **request_buffer, UCHAR *request_buffer_end);
58 static UINT _nx_rtsp_server_request_header_parse(NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr, UCHAR **request_buffer, UCHAR *request_buffer_end);
59 static UINT _nx_rtsp_server_response_create(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr);
60 static UINT _nx_rtsp_server_response_send(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr);
61 
62 static VOID _nx_rtsp_server_disconnect(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr);
63 
64 static UINT _nx_rtsp_server_memicmp(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length);
65 static UCHAR *_nx_rtsp_server_strstr(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length);
66 
67 /* Define macros.  */
68 
69 #define NX_RTSP_SERVER_STRING_SIZE(str)         sizeof(str) - 1
70 #define NX_RTSP_SERVER_STRING_WITH_SIZE(str)    (UCHAR *)str, NX_RTSP_SERVER_STRING_SIZE(str)
71 
72 /* Bring in externs for caller checking code.  */
73 
74 NX_CALLER_CHECKING_EXTERNS
75 
76 /* Define description table for the RTSP response status code.  */
77 
78 const NX_RTSP_RESPONSE nx_rtsp_server_response_description_table[] =
79 {
80     { NX_RTSP_STATUS_CODE_OK                                  , "OK" },
81     { NX_RTSP_STATUS_CODE_CREATED                             , "CREATED" },
82     { NX_RTSP_STATUS_CODE_LOW_ON_STORAGE_SPACE                , "LOW ON STORAGE SPACE" },
83     { NX_RTSP_STATUS_CODE_MULTIPLE_CHOICES                    , "MULTIPLE CHOICES" },
84     { NX_RTSP_STATUS_CODE_MOVED_PERMANENTLY                   , "MOVED PERMANENTLY" },
85     { NX_RTSP_STATUS_CODE_MOVED_TEMPORARILY                   , "MOVED TEMPORARILY" },
86     { NX_RTSP_STATUS_CODE_SEE_OTHER                           , "SEE OTHER" },
87     { NX_RTSP_STATUS_CODE_NOT_MODIFIED                        , "NOT MODIFIED" },
88     { NX_RTSP_STATUS_CODE_USE_PROXY                           , "USE PROXY" },
89     { NX_RTSP_STATUS_CODE_GOING_AWAY                          , "GOING AWAY" },
90     { NX_RTSP_STATUS_CODE_LOAD_BALANCING                      , "LOAD BALANCING" },
91     { NX_RTSP_STATUS_CODE_BAD_REQUEST                         , "BAD REQUEST" },
92     { NX_RTSP_STATUS_CODE_UNAUTHORIZED                        , "UNAUTHORIZED" },
93     { NX_RTSP_STATUS_CODE_PAYMENT_REQUIRED                    , "PAYMENT REQUIRED" },
94     { NX_RTSP_STATUS_CODE_FORBIDDEN                           , "FORBIDDEN" },
95     { NX_RTSP_STATUS_CODE_NOT_FOUND                           , "NOT FOUND" },
96     { NX_RTSP_STATUS_CODE_METHOD_NOT_ALLOWED                  , "METHOD NOT ALLOWED" },
97     { NX_RTSP_STATUS_CODE_NOT_ACCEPTABLE                      , "NOT ACCEPTABLE" },
98     { NX_RTSP_STATUS_CODE_PROXY_AUTHENTICATION_REQUIRED       , "PROXY AUTHENTICATION REQUIRED" },
99     { NX_RTSP_STATUS_CODE_REQUEST_TIMEOUT                     , "REQUEST TIMEOUT" },
100     { NX_RTSP_STATUS_CODE_GONE                                , "GONE" },
101     { NX_RTSP_STATUS_CODE_LENGTH_REQUIRED                     , "LENGTH REQUIRED" },
102     { NX_RTSP_STATUS_CODE_PRECONDITION_FAILED                 , "PRECONDITION FAILED" },
103     { NX_RTSP_STATUS_CODE_REQUEST_ENTITY_TOO_LARGE            , "REQUEST ENTITY TOO LARGE" },
104     { NX_RTSP_STATUS_CODE_REQUESTURI_TOO_LARGE                , "REQUESTURI TOO LARGE" },
105     { NX_RTSP_STATUS_CODE_UNSUPPORTED_MEDIA_TYPE              , "UNSUPPORTED MEDIA TYPE" },
106     { NX_RTSP_STATUS_CODE_PARAMETER_NOT_UNDERSTOOD            , "PARAMETER NOT UNDERSTOOD" },
107     { NX_RTSP_STATUS_CODE_RESERVED                            , "RESERVED" },
108     { NX_RTSP_STATUS_CODE_NOT_ENOUGH_BANDWIDTH                , "NOT ENOUGH BANDWIDTH" },
109     { NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND                   , "SESSION NOT FOUND" },
110     { NX_RTSP_STATUS_CODE_METHOD_NOT_VALID_IN_THIS_STATE      , "METHOD NOT VALID IN THIS STATE" },
111     { NX_RTSP_STATUS_CODE_HEADER_FIELD_NOT_VALID_FOR_RESOURCE , "HEADER FIELD NOT VALID FOR RESOURCE" },
112     { NX_RTSP_STATUS_CODE_INVALID_RANGE                       , "INVALID RANGE" },
113     { NX_RTSP_STATUS_CODE_PARAMETER_IS_READONLY               , "PARAMETER IS READONLY" },
114     { NX_RTSP_STATUS_CODE_AGGREGATE_OPERATION_NOT_ALLOWED     , "AGGREGATE OPERATION NOT ALLOWED" },
115     { NX_RTSP_STATUS_CODE_ONLY_AGGREGATE_OPERATION_ALLOWED    , "ONLY AGGREGATE OPERATION ALLOWED" },
116     { NX_RTSP_STATUS_CODE_UNSUPPORTED_TRANSPORT               , "UNSUPPORTED TRANSPORT" },
117     { NX_RTSP_STATUS_CODE_DESTINATION_UNREACHABLE             , "DESTINATION UNREACHABLE" },
118     { NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR               , "INTERNAL SERVER ERROR" },
119     { NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED                     , "NOT IMPLEMENTED" },
120     { NX_RTSP_STATUS_CODE_BAD_GATEWAY                         , "BAD GATEWAY" },
121     { NX_RTSP_STATUS_CODE_SERVICE_UNAVAILABLE                 , "SERVICE UNAVAILABLE" },
122     { NX_RTSP_STATUS_CODE_GATEWAY_TIMEOUT                     , "GATEWAY TIMEOUT" },
123     { NX_RTSP_STATUS_CODE_RTSP_VERSION_NOT_SUPPORTED          , "RTSP VERSION NOT SUPPORTED" },
124     { NX_RTSP_STATUS_CODE_OPTION_NOT_SUPPORTED                , "OPTION NOT SUPPORTED" },
125     { NX_NULL                                                 , "" }
126 };
127 
128 /**************************************************************************/
129 /*                                                                        */
130 /*  FUNCTION                                               RELEASE        */
131 /*                                                                        */
132 /*    _nxe_rtsp_server_create                             PORTABLE C      */
133 /*                                                           6.3.0        */
134 /*  AUTHOR                                                                */
135 /*                                                                        */
136 /*    Wenhui Xie, Microsoft Corporation                                   */
137 /*                                                                        */
138 /*  DESCRIPTION                                                           */
139 /*                                                                        */
140 /*    This function checks for errors in RTSP server create function call.*/
141 /*                                                                        */
142 /*  INPUT                                                                 */
143 /*                                                                        */
144 /*    rtsp_server_ptr                       Pointer to RTSP server        */
145 /*    server_name                           Name of RTSP server           */
146 /*    server_name_length                    Length of RTSP server name    */
147 /*    ip_ptr                                Pointer to IP instance        */
148 /*    rtsp_packet_pool                      Pointer to packet pool        */
149 /*    stack_ptr                             Server thread's stack pointer */
150 /*    stack_size                            Server thread's stack size    */
151 /*    priority                              The priority of the thread    */
152 /*    server_port                           Listening port                */
153 /*    disconnect_callback                   Disconnect callback function  */
154 /*                                                                        */
155 /*  OUTPUT                                                                */
156 /*                                                                        */
157 /*    status                                Completion status             */
158 /*                                                                        */
159 /*  CALLS                                                                 */
160 /*                                                                        */
161 /*    _nx_rtsp_server_create                Create RTSP server            */
162 /*                                                                        */
163 /*  CALLED BY                                                             */
164 /*                                                                        */
165 /*    Application Code                                                    */
166 /*                                                                        */
167 /*  RELEASE HISTORY                                                       */
168 /*                                                                        */
169 /*    DATE              NAME                      DESCRIPTION             */
170 /*                                                                        */
171 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
172 /*                                                                        */
173 /**************************************************************************/
_nxe_rtsp_server_create(NX_RTSP_SERVER * rtsp_server_ptr,CHAR * server_name,UINT server_name_length,NX_IP * ip_ptr,NX_PACKET_POOL * rtsp_packet_pool,VOID * stack_ptr,ULONG stack_size,UINT priority,UINT server_port,UINT (* disconnect_callback)(NX_RTSP_CLIENT * rtsp_client_ptr))174 UINT _nxe_rtsp_server_create(NX_RTSP_SERVER *rtsp_server_ptr, CHAR *server_name, UINT server_name_length,
175                              NX_IP *ip_ptr, NX_PACKET_POOL *rtsp_packet_pool,
176                              VOID *stack_ptr, ULONG stack_size, UINT priority, UINT server_port,
177                              UINT (*disconnect_callback)(NX_RTSP_CLIENT *rtsp_client_ptr))
178 {
179 UINT status;
180 
181 
182     /* Check for invalid input pointers.  */
183     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
184         (rtsp_server_ptr == NX_NULL) || (stack_ptr == NX_NULL) ||
185         (rtsp_packet_pool == NX_NULL) || rtsp_server_ptr -> nx_rtsp_server_id == NX_RTSP_SERVER_ID)
186     {
187         return(NX_PTR_ERROR);
188     }
189 
190     /* Call actual RTSP server create function.  */
191     status = _nx_rtsp_server_create(rtsp_server_ptr,server_name, server_name_length, ip_ptr, rtsp_packet_pool,
192                                     stack_ptr, stack_size, priority,  server_port, disconnect_callback);
193 
194     /* Return status.  */
195     return(status);
196 }
197 
198 /**************************************************************************/
199 /*                                                                        */
200 /*  FUNCTION                                               RELEASE        */
201 /*                                                                        */
202 /*    _nx_rtsp_server_create                              PORTABLE C      */
203 /*                                                           6.3.0        */
204 /*  AUTHOR                                                                */
205 /*                                                                        */
206 /*    Wenhui Xie, Microsoft Corporation                                   */
207 /*                                                                        */
208 /*  DESCRIPTION                                                           */
209 /*                                                                        */
210 /*    This function creates a RTSP server on the specified IP and port.   */
211 /*                                                                        */
212 /*  INPUT                                                                 */
213 /*                                                                        */
214 /*    rtsp_server_ptr                       Pointer to RTSP server        */
215 /*    server_name                           Name of RTSP server           */
216 /*    server_name_length                    Length of RTSP server name    */
217 /*    ip_ptr                                Pointer to IP instance        */
218 /*    rtsp_packet_pool                      Pointer to packet pool        */
219 /*    stack_ptr                             Server thread's stack pointer */
220 /*    stack_size                            Server thread's stack size    */
221 /*    priority                              The priority of the thread    */
222 /*    server_port                           Listening port                */
223 /*    disconnect_callback                   Disconnect callback function  */
224 /*                                                                        */
225 /*  OUTPUT                                                                */
226 /*                                                                        */
227 /*    status                                Completion status             */
228 /*                                                                        */
229 /*  CALLS                                                                 */
230 /*                                                                        */
231 /*    memset                                Reset memory                  */
232 /*    tx_event_flags_create                 Create thread event flags     */
233 /*    tx_thread_create                      Create the server thread      */
234 /*    tx_timer_create                       Create the timeout timer      */
235 /*    tx_event_flags_delete                 Delete thread event flags     */
236 /*    tx_thread_delete                      Delete the server thread      */
237 /*                                                                        */
238 /*  CALLED BY                                                             */
239 /*                                                                        */
240 /*    Application Code                                                    */
241 /*                                                                        */
242 /*  RELEASE HISTORY                                                       */
243 /*                                                                        */
244 /*    DATE              NAME                      DESCRIPTION             */
245 /*                                                                        */
246 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
247 /*                                                                        */
248 /**************************************************************************/
_nx_rtsp_server_create(NX_RTSP_SERVER * rtsp_server_ptr,CHAR * server_name,UINT server_name_length,NX_IP * ip_ptr,NX_PACKET_POOL * rtsp_packet_pool,VOID * stack_ptr,ULONG stack_size,UINT priority,UINT server_port,UINT (* disconnect_callback)(NX_RTSP_CLIENT * rtsp_client_ptr))249 UINT _nx_rtsp_server_create(NX_RTSP_SERVER *rtsp_server_ptr, CHAR *server_name, UINT server_name_length,
250                             NX_IP *ip_ptr, NX_PACKET_POOL *rtsp_packet_pool,
251                             VOID *stack_ptr, ULONG stack_size, UINT priority, UINT server_port,
252                             UINT (*disconnect_callback)(NX_RTSP_CLIENT *rtsp_client_ptr))
253 {
254 UINT status;
255 
256 
257     /* Clear RTSP server object.  */
258     memset((VOID *)rtsp_server_ptr, 0, sizeof(NX_RTSP_SERVER));
259 
260     /* Set the RTSP server name.  */
261     rtsp_server_ptr -> nx_rtsp_server_name = server_name;
262     rtsp_server_ptr -> nx_rtsp_server_name_length = server_name_length;
263 
264     /* Record our packet pool.  */
265     rtsp_server_ptr -> nx_rtsp_server_packet_pool = rtsp_packet_pool;
266 
267     /* Create the ThreadX event flags. These will be used to drive the RTSP server thread.  */
268     status = tx_event_flags_create(&(rtsp_server_ptr -> nx_rtsp_server_event_flags), "RTSP Server Thread Events");
269 
270     if (status)
271     {
272         return(status);
273     }
274 
275     /* Create the RTSP server thread and start the RTSP server.  */
276     status = tx_thread_create(&(rtsp_server_ptr -> nx_rtsp_server_thread), server_name,
277                               _nx_rtsp_server_thread_entry, (ULONG)rtsp_server_ptr,
278                               stack_ptr, stack_size, priority, priority,
279                               NX_RTSP_SERVER_TIME_SLICE, TX_NO_ACTIVATE);
280 
281     if (status)
282     {
283 
284         /* Delete the event flag.  */
285         tx_event_flags_delete(&(rtsp_server_ptr -> nx_rtsp_server_event_flags));
286         return(status);
287     }
288 
289     /* Create the timeout timer.  */
290     status = tx_timer_create(&(rtsp_server_ptr -> nx_rtsp_server_timer), "RTSP Server Timer",
291                              _nx_rtsp_server_timeout, (ULONG)rtsp_server_ptr,
292                              NX_IP_PERIODIC_RATE, NX_IP_PERIODIC_RATE, TX_NO_ACTIVATE);
293 
294     if (status)
295     {
296 
297         /* Delete the thread.  */
298         tx_thread_delete(&(rtsp_server_ptr -> nx_rtsp_server_thread));
299 
300         /* Delete the event flag.  */
301         tx_event_flags_delete(&(rtsp_server_ptr -> nx_rtsp_server_event_flags));
302 
303         return(status);
304     }
305 
306     /* Set the IP pointer.  */
307     rtsp_server_ptr -> nx_rtsp_server_ip_ptr = ip_ptr;
308 
309     /* Set the TCP port of RTSP server.  */
310     rtsp_server_ptr -> nx_rtsp_server_port = (USHORT)server_port;
311 
312     /* Set disconnect callback function.  */
313     rtsp_server_ptr -> nx_rtsp_server_disconnect_callback = disconnect_callback;
314 
315     /* Set the RTSP server ID.  */
316     rtsp_server_ptr -> nx_rtsp_server_id = NX_RTSP_SERVER_ID;
317 
318     return(NX_SUCCESS);
319 }
320 
321 /**************************************************************************/
322 /*                                                                        */
323 /*  FUNCTION                                               RELEASE        */
324 /*                                                                        */
325 /*    _nxe_rtsp_server_delete                             PORTABLE C      */
326 /*                                                           6.3.0        */
327 /*  AUTHOR                                                                */
328 /*                                                                        */
329 /*    Wenhui Xie, Microsoft Corporation                                   */
330 /*                                                                        */
331 /*  DESCRIPTION                                                           */
332 /*                                                                        */
333 /*    This function checks for errors in RTSP server delete function call.*/
334 /*                                                                        */
335 /*  INPUT                                                                 */
336 /*                                                                        */
337 /*    rtsp_server_ptr                       Pointer to RTSP server        */
338 /*                                                                        */
339 /*  OUTPUT                                                                */
340 /*                                                                        */
341 /*    status                                Completion status             */
342 /*                                                                        */
343 /*  CALLS                                                                 */
344 /*                                                                        */
345 /*    _nx_rtsp_server_delete                Delete the RTSP server        */
346 /*                                                                        */
347 /*  CALLED BY                                                             */
348 /*                                                                        */
349 /*    Application Code                                                    */
350 /*                                                                        */
351 /*  RELEASE HISTORY                                                       */
352 /*                                                                        */
353 /*    DATE              NAME                      DESCRIPTION             */
354 /*                                                                        */
355 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
356 /*                                                                        */
357 /**************************************************************************/
_nxe_rtsp_server_delete(NX_RTSP_SERVER * rtsp_server_ptr)358 UINT _nxe_rtsp_server_delete(NX_RTSP_SERVER *rtsp_server_ptr)
359 {
360 UINT status;
361 
362 
363     /* Check for invalid input pointers.  */
364     if ((rtsp_server_ptr == NX_NULL) || (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
365     {
366         return(NX_PTR_ERROR);
367     }
368 
369     /* Call actual RTSP server delete function.  */
370     status = _nx_rtsp_server_delete(rtsp_server_ptr);
371 
372     /* Return status.  */
373     return(status);
374 }
375 
376 /**************************************************************************/
377 /*                                                                        */
378 /*  FUNCTION                                               RELEASE        */
379 /*                                                                        */
380 /*    _nx_rtsp_server_delete                              PORTABLE C      */
381 /*                                                           6.3.0        */
382 /*  AUTHOR                                                                */
383 /*                                                                        */
384 /*    Wenhui Xie, Microsoft Corporation                                   */
385 /*                                                                        */
386 /*  DESCRIPTION                                                           */
387 /*                                                                        */
388 /*    This function deletes a previously created RTSP server on specified */
389 /*    IP and port.                                                        */
390 /*                                                                        */
391 /*  INPUT                                                                 */
392 /*                                                                        */
393 /*    rtsp_server_ptr                       Pointer to RTSP server        */
394 /*                                                                        */
395 /*  OUTPUT                                                                */
396 /*                                                                        */
397 /*    status                                Completion status             */
398 /*                                                                        */
399 /*  CALLS                                                                 */
400 /*                                                                        */
401 /*    _nx_rtsp_server_stop                  Stop the RTSP server          */
402 /*    tx_thread_terminate                   Terminate server thread       */
403 /*    tx_event_flags_delete                 Delete thread event flags     */
404 /*    tx_thread_delete                      Delete the server thread      */
405 /*    tx_timer_delete                       Delete the timeout timer      */
406 /*                                                                        */
407 /*  CALLED BY                                                             */
408 /*                                                                        */
409 /*    Application Code                                                    */
410 /*                                                                        */
411 /*  RELEASE HISTORY                                                       */
412 /*                                                                        */
413 /*    DATE              NAME                      DESCRIPTION             */
414 /*                                                                        */
415 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
416 /*                                                                        */
417 /**************************************************************************/
_nx_rtsp_server_delete(NX_RTSP_SERVER * rtsp_server_ptr)418 UINT _nx_rtsp_server_delete(NX_RTSP_SERVER *rtsp_server_ptr)
419 {
420 
421 
422     /* Stop the RTSP server if not done yet. */
423     if (rtsp_server_ptr -> nx_rtsp_server_started)
424     {
425         _nx_rtsp_server_stop(rtsp_server_ptr);
426     }
427 
428     /* Terminate server thread. */
429     tx_thread_terminate(&(rtsp_server_ptr -> nx_rtsp_server_thread));
430 
431     /* Delete server thread.  */
432     tx_thread_delete(&(rtsp_server_ptr -> nx_rtsp_server_thread));
433 
434     /* Delete the server event flags.  */
435     tx_event_flags_delete(&(rtsp_server_ptr -> nx_rtsp_server_event_flags));
436 
437     /* Delete the timer.  */
438     tx_timer_delete(&(rtsp_server_ptr -> nx_rtsp_server_timer));
439 
440     /* Clear the RTSP server ID.  */
441     rtsp_server_ptr -> nx_rtsp_server_id = 0;
442 
443     return(NX_SUCCESS);
444 }
445 
446 /**************************************************************************/
447 /*                                                                        */
448 /*  FUNCTION                                               RELEASE        */
449 /*                                                                        */
450 /*    _nxe_rtsp_server_start                              PORTABLE C      */
451 /*                                                           6.3.0        */
452 /*  AUTHOR                                                                */
453 /*                                                                        */
454 /*    Wenhui Xie, Microsoft Corporation                                   */
455 /*                                                                        */
456 /*  DESCRIPTION                                                           */
457 /*                                                                        */
458 /*    This function checks for errors in RTSP server start function call. */
459 /*                                                                        */
460 /*  INPUT                                                                 */
461 /*                                                                        */
462 /*    rtsp_server_ptr                       Pointer to RTSP server        */
463 /*                                                                        */
464 /*  OUTPUT                                                                */
465 /*                                                                        */
466 /*    status                                Completion status             */
467 /*                                                                        */
468 /*  CALLS                                                                 */
469 /*                                                                        */
470 /*    _nx_rtsp_server_start                 Start the RTSP server         */
471 /*                                                                        */
472 /*  CALLED BY                                                             */
473 /*                                                                        */
474 /*    Application Code                                                    */
475 /*                                                                        */
476 /*  RELEASE HISTORY                                                       */
477 /*                                                                        */
478 /*    DATE              NAME                      DESCRIPTION             */
479 /*                                                                        */
480 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
481 /*                                                                        */
482 /**************************************************************************/
_nxe_rtsp_server_start(NX_RTSP_SERVER * rtsp_server_ptr)483 UINT _nxe_rtsp_server_start(NX_RTSP_SERVER *rtsp_server_ptr)
484 {
485 UINT   status;
486 
487 
488     /* Check for invalid input pointers.  */
489     if ((rtsp_server_ptr == NX_NULL) || (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
490     {
491         return(NX_PTR_ERROR);
492     }
493 
494     /* Call actual RTSP server start function.  */
495     status = _nx_rtsp_server_start(rtsp_server_ptr);
496 
497     /* Return status.  */
498     return(status);
499 }
500 
501 /**************************************************************************/
502 /*                                                                        */
503 /*  FUNCTION                                               RELEASE        */
504 /*                                                                        */
505 /*    _nx_rtsp_server_start                               PORTABLE C      */
506 /*                                                           6.3.0        */
507 /*  AUTHOR                                                                */
508 /*                                                                        */
509 /*    Wenhui Xie, Microsoft Corporation                                   */
510 /*                                                                        */
511 /*  DESCRIPTION                                                           */
512 /*                                                                        */
513 /*    This function starts a previously created RTSP server.              */
514 /*                                                                        */
515 /*  INPUT                                                                 */
516 /*                                                                        */
517 /*    rtsp_server_ptr                       Pointer to RTSP server        */
518 /*                                                                        */
519 /*  OUTPUT                                                                */
520 /*                                                                        */
521 /*    status                                Completion status             */
522 /*                                                                        */
523 /*  CALLS                                                                 */
524 /*                                                                        */
525 /*    nx_tcp_socket_create                  Create TCP socket             */
526 /*    nx_tcp_socket_receive_notify          Set TCP notification callback */
527 /*    nx_tcp_socket_delete                  Delete TCP socket             */
528 /*    nx_tcp_server_socket_listen           Listen on free TCP socket     */
529 /*    tx_thread_resume                      Resume the RTSP server thread */
530 /*    tx_timer_activate                     Activate the timeout timer    */
531 /*                                                                        */
532 /*  CALLED BY                                                             */
533 /*                                                                        */
534 /*    Application Code                                                    */
535 /*                                                                        */
536 /*  RELEASE HISTORY                                                       */
537 /*                                                                        */
538 /*    DATE              NAME                      DESCRIPTION             */
539 /*                                                                        */
540 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
541 /*                                                                        */
542 /**************************************************************************/
_nx_rtsp_server_start(NX_RTSP_SERVER * rtsp_server_ptr)543 UINT _nx_rtsp_server_start(NX_RTSP_SERVER *rtsp_server_ptr)
544 {
545 UINT   status;
546 int    i, j;
547 
548 
549     /* Check if the RTSP server is started.  */
550     if (rtsp_server_ptr -> nx_rtsp_server_started)
551     {
552         return(NX_RTSP_SERVER_ALREADY_STARTED);
553     }
554 
555     /* Check if the required method callbacks are set.  */
556     if ((rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_setup_callback == NX_NULL) ||
557         (rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_play_callback == NX_NULL) ||
558         (rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_teardown_callback == NX_NULL))
559     {
560         return(NX_RTSP_SERVER_MISSING_REQUIRED_CALLBACKS);
561     }
562 
563     /* Loop to create all the RTSP client control sockets.  */
564     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
565     {
566 
567         /* Create an RTSP client control socket.  */
568         status =  nx_tcp_socket_create(rtsp_server_ptr -> nx_rtsp_server_ip_ptr, &(rtsp_server_ptr -> nx_rtsp_server_client_list[i].nx_rtsp_client_socket),
569                                        "RTSP Client Control Socket", NX_RTSP_SERVER_TYPE_OF_SERVICE, NX_RTSP_SERVER_FRAGMENT_OPTION,
570                                        NX_RTSP_SERVER_TIME_TO_LIVE, NX_RTSP_SERVER_WINDOW_SIZE, NX_NULL,
571                                        _nx_rtsp_server_disconnect_present);
572 
573         /* If no error is present, register the receive notify function.  */
574         if (status == NX_SUCCESS)
575         {
576 
577             /* Register the receive function.  */
578             nx_tcp_socket_receive_notify(&(rtsp_server_ptr -> nx_rtsp_server_client_list[i].nx_rtsp_client_socket),
579                                          _nx_rtsp_server_request_present);
580         }
581         else
582         {
583             break;
584         }
585 
586         /* Make sure each socket points to the RTSP server.  */
587         rtsp_server_ptr -> nx_rtsp_server_client_list[i].nx_rtsp_client_socket.nx_tcp_socket_reserved_ptr = rtsp_server_ptr;
588     }
589 
590     /* Determine if an error has occurred.  */
591     if (status)
592     {
593 
594         /* Loop to delete any created sockets.  */
595         for (j = 0; j < i; j++)
596         {
597 
598             /* Delete the RTSP socket.  */
599             nx_tcp_socket_delete(&(rtsp_server_ptr -> nx_rtsp_server_client_list[j].nx_rtsp_client_socket));
600         }
601 
602         /* Return an error.  */
603         return(status);
604     }
605 
606 
607     /* Start listening on the RTSP socket.  */
608     status =  nx_tcp_server_socket_listen(rtsp_server_ptr -> nx_rtsp_server_ip_ptr, rtsp_server_ptr -> nx_rtsp_server_port,
609                                           &(rtsp_server_ptr -> nx_rtsp_server_client_list[0].nx_rtsp_client_socket),
610                                           NX_RTSP_SERVER_MAX_CLIENTS, _nx_rtsp_server_connect_present);
611 
612     if (status)
613     {
614         return(status);
615     }
616 
617     /* Start thread. */
618     tx_thread_resume(&rtsp_server_ptr -> nx_rtsp_server_thread);
619 
620     /* Activate timer.  */
621     tx_timer_activate(&rtsp_server_ptr -> nx_rtsp_server_timer);
622 
623     rtsp_server_ptr -> nx_rtsp_server_started = NX_TRUE;
624 
625     return(NX_SUCCESS);
626 }
627 
628 /**************************************************************************/
629 /*                                                                        */
630 /*  FUNCTION                                               RELEASE        */
631 /*                                                                        */
632 /*    _nxe_rtsp_server_stop                               PORTABLE C      */
633 /*                                                           6.3.0        */
634 /*  AUTHOR                                                                */
635 /*                                                                        */
636 /*    Wenhui Xie, Microsoft Corporation                                   */
637 /*                                                                        */
638 /*  DESCRIPTION                                                           */
639 /*                                                                        */
640 /*    This function checks for errors in RTSP server stop function call.  */
641 /*                                                                        */
642 /*  INPUT                                                                 */
643 /*                                                                        */
644 /*    rtsp_server_ptr                       Pointer to RTSP server        */
645 /*                                                                        */
646 /*  OUTPUT                                                                */
647 /*                                                                        */
648 /*    status                                Completion status             */
649 /*                                                                        */
650 /*  CALLS                                                                 */
651 /*                                                                        */
652 /*    _nx_rtsp_server_stop                  Stop the RTSP server          */
653 /*                                                                        */
654 /*  CALLED BY                                                             */
655 /*                                                                        */
656 /*    Application Code                                                    */
657 /*                                                                        */
658 /*  RELEASE HISTORY                                                       */
659 /*                                                                        */
660 /*    DATE              NAME                      DESCRIPTION             */
661 /*                                                                        */
662 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
663 /*                                                                        */
664 /**************************************************************************/
_nxe_rtsp_server_stop(NX_RTSP_SERVER * rtsp_server_ptr)665 UINT _nxe_rtsp_server_stop(NX_RTSP_SERVER *rtsp_server_ptr)
666 {
667 UINT status;
668 
669 
670     /* Check for invalid input pointers.  */
671     if ((rtsp_server_ptr == NX_NULL) || (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
672     {
673         return(NX_PTR_ERROR);
674     }
675 
676     /* Call actual RTSP server stop function.  */
677     status = _nx_rtsp_server_stop(rtsp_server_ptr);
678 
679     /* Return status.  */
680     return(status);
681 }
682 
683 /**************************************************************************/
684 /*                                                                        */
685 /*  FUNCTION                                               RELEASE        */
686 /*                                                                        */
687 /*    _nx_rtsp_server_stop                                PORTABLE C      */
688 /*                                                           6.3.0        */
689 /*  AUTHOR                                                                */
690 /*                                                                        */
691 /*    Wenhui Xie, Microsoft Corporation                                   */
692 /*                                                                        */
693 /*  DESCRIPTION                                                           */
694 /*                                                                        */
695 /*    This function stops a previously started RTSP server.               */
696 /*                                                                        */
697 /*  INPUT                                                                 */
698 /*                                                                        */
699 /*    rtsp_server_ptr                       Pointer to RTSP server        */
700 /*                                                                        */
701 /*  OUTPUT                                                                */
702 /*                                                                        */
703 /*    status                                Completion status             */
704 /*                                                                        */
705 /*  CALLS                                                                 */
706 /*                                                                        */
707 /*    tx_thread_suspend                     Suspend server thread         */
708 /*    tx_timer_deactivate                   Stop server timeout timer     */
709 /*    nx_tcp_socket_disconnect              Disconnect TCP socket         */
710 /*    nx_tcp_server_socket_unaccept         Clear accepted socket         */
711 /*    nx_tcp_socket_delete                  Delete TCP socket             */
712 /*    nx_tcp_server_socket_unlisten         Stop listening on TCP socket  */
713 /*                                                                        */
714 /*  CALLED BY                                                             */
715 /*                                                                        */
716 /*    Application Code                                                    */
717 /*                                                                        */
718 /*  RELEASE HISTORY                                                       */
719 /*                                                                        */
720 /*    DATE              NAME                      DESCRIPTION             */
721 /*                                                                        */
722 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
723 /*                                                                        */
724 /**************************************************************************/
_nx_rtsp_server_stop(NX_RTSP_SERVER * rtsp_server_ptr)725 UINT _nx_rtsp_server_stop(NX_RTSP_SERVER *rtsp_server_ptr)
726 {
727 UINT client_index;
728 
729 
730     /* Check if the server is started.  */
731     if (rtsp_server_ptr -> nx_rtsp_server_started != NX_TRUE)
732     {
733         return(NX_RTSP_SERVER_NOT_STARTED);
734     }
735 
736     /* Suspend thread. */
737     tx_thread_suspend(&(rtsp_server_ptr -> nx_rtsp_server_thread));
738 
739     /* Deactivate the timer.  */
740     tx_timer_deactivate(&(rtsp_server_ptr -> nx_rtsp_server_timer));
741 
742     /* Walk through to close the sockets.  */
743     for (client_index = 0; client_index < NX_RTSP_SERVER_MAX_CLIENTS; client_index++)
744     {
745 
746         /* Disconnect the socket.  */
747         nx_tcp_socket_disconnect(&(rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_socket), NX_NO_WAIT);
748 
749         /* Unaccept the socket.  */
750         nx_tcp_server_socket_unaccept(&(rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_socket));
751 
752         /* Delete the socket.  */
753         nx_tcp_socket_delete(&(rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_socket));
754 
755         /* Check to see if a packet is queued up.  */
756         if (rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_request_packet)
757         {
758 
759             /* Yes, release it!  */
760             nx_packet_release(rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_request_packet);
761             rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_request_packet = NX_NULL;
762             rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_request_bytes_total = 0;
763         }
764 
765         /* Check to see if a packet is queued up.  */
766         if (rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_response_packet)
767         {
768 
769             /* Yes, release it!  */
770             nx_packet_release(rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_response_packet);
771             rtsp_server_ptr -> nx_rtsp_server_client_list[client_index].nx_rtsp_client_response_packet = NX_NULL;
772         }
773     }
774 
775     /* Unlisten for the RTSP server port.  */
776     nx_tcp_server_socket_unlisten(rtsp_server_ptr -> nx_rtsp_server_ip_ptr, rtsp_server_ptr -> nx_rtsp_server_port);
777 
778     /* Clear the RTSP server started flag.  */
779     rtsp_server_ptr -> nx_rtsp_server_started = NX_FALSE;
780 
781     return(NX_SUCCESS);
782 }
783 
784 /**************************************************************************/
785 /*                                                                        */
786 /*  FUNCTION                                               RELEASE        */
787 /*                                                                        */
788 /*    _nxe_rtsp_server_sdp_set                            PORTABLE C      */
789 /*                                                           6.3.0        */
790 /*  AUTHOR                                                                */
791 /*                                                                        */
792 /*    Wenhui Xie, Microsoft Corporation                                   */
793 /*                                                                        */
794 /*  DESCRIPTION                                                           */
795 /*                                                                        */
796 /*    This function checks for errors in SDP set function call.           */
797 /*                                                                        */
798 /*  INPUT                                                                 */
799 /*                                                                        */
800 /*    rtsp_client_ptr                       Pointer to RTSP client        */
801 /*    sdp_string                            Pointer to SDP string         */
802 /*    sdp_length                            The length of the SDP string  */
803 /*                                                                        */
804 /*  OUTPUT                                                                */
805 /*                                                                        */
806 /*    status                                Completion status             */
807 /*                                                                        */
808 /*  CALLS                                                                 */
809 /*                                                                        */
810 /*    _nx_rtsp_server_sdp_set               Set SDP string in response    */
811 /*                                                                        */
812 /*  CALLED BY                                                             */
813 /*                                                                        */
814 /*    Application Code                                                    */
815 /*                                                                        */
816 /*  RELEASE HISTORY                                                       */
817 /*                                                                        */
818 /*    DATE              NAME                      DESCRIPTION             */
819 /*                                                                        */
820 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
821 /*                                                                        */
822 /**************************************************************************/
_nxe_rtsp_server_sdp_set(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * sdp_string,UINT sdp_length)823 UINT _nxe_rtsp_server_sdp_set(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *sdp_string, UINT sdp_length)
824 {
825 UINT status;
826 
827 
828     /* Check for invalid input pointers.  */
829     if ((rtsp_client_ptr == NX_NULL) || (sdp_string == NX_NULL) || (sdp_length == 0) ||
830         (rtsp_client_ptr -> nx_rtsp_client_server_ptr == NX_NULL) ||
831         (rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
832     {
833         return(NX_PTR_ERROR);
834     }
835 
836     /* Call actual SDP set function.  */
837     status = _nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp_string, sdp_length);
838 
839     /* Return status.  */
840     return(status);
841 }
842 
843 /**************************************************************************/
844 /*                                                                        */
845 /*  FUNCTION                                               RELEASE        */
846 /*                                                                        */
847 /*    _nx_rtsp_server_sdp_set                             PORTABLE C      */
848 /*                                                           6.3.0        */
849 /*  AUTHOR                                                                */
850 /*                                                                        */
851 /*    Wenhui Xie, Microsoft Corporation                                   */
852 /*                                                                        */
853 /*  DESCRIPTION                                                           */
854 /*                                                                        */
855 /*    This function sets the SDP string to the response packet. This      */
856 /*    function can only be called in DESCRIBE callback function.          */
857 /*                                                                        */
858 /*  INPUT                                                                 */
859 /*                                                                        */
860 /*    rtsp_client_ptr                       Pointer to RTSP client        */
861 /*    sdp_string                            Pointer to SDP string         */
862 /*    sdp_length                            The length of the SDP string  */
863 /*                                                                        */
864 /*  OUTPUT                                                                */
865 /*                                                                        */
866 /*    status                                Completion status             */
867 /*                                                                        */
868 /*  CALLS                                                                 */
869 /*                                                                        */
870 /*    nx_packet_data_append                 Append packet data            */
871 /*    _nx_utility_uint_to_string            Convert integer to string     */
872 /*                                                                        */
873 /*  CALLED BY                                                             */
874 /*                                                                        */
875 /*    Application Code                                                    */
876 /*                                                                        */
877 /*  RELEASE HISTORY                                                       */
878 /*                                                                        */
879 /*    DATE              NAME                      DESCRIPTION             */
880 /*                                                                        */
881 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
882 /*                                                                        */
883 /**************************************************************************/
_nx_rtsp_server_sdp_set(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * sdp_string,UINT sdp_length)884 UINT _nx_rtsp_server_sdp_set(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *sdp_string, UINT sdp_length)
885 {
886 UINT       status;
887 CHAR       temp_buffer[11];
888 UINT       temp_length;
889 NX_PACKET *response_packet_ptr = rtsp_client_ptr -> nx_rtsp_client_response_packet;
890 
891 
892     /* Check if the packet is valid.  */
893     if (!response_packet_ptr)
894     {
895         return(NX_RTSP_SERVER_NO_PACKET);
896     }
897 
898     /* Check the request method.  */
899     if ((!rtsp_client_ptr -> nx_rtsp_client_request_ptr) ||
900         (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_method != NX_RTSP_METHOD_DESCRIBE))
901     {
902         return(NX_RTSP_SERVER_INVALID_REQUEST);
903     }
904 
905     /* Add "Content-Type" header.  */
906     status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Content-Type: "),
907                                    rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
908     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(NX_RTSP_SERVER_CONTENT_TYPE_SDP),
909                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
910     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
911                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
912 
913     /* Add "Content-Length" header.  */
914     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Content-Length: "),
915                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
916     temp_length = _nx_utility_uint_to_string(sdp_length, 10, temp_buffer, sizeof(temp_buffer));
917     status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length,
918                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
919     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n\r\n"),
920                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
921 
922     /* Add sdp string.  */
923     status += nx_packet_data_append(response_packet_ptr, sdp_string, sdp_length,
924                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
925 
926     return(status);
927 }
928 
929 /**************************************************************************/
930 /*                                                                        */
931 /*  FUNCTION                                               RELEASE        */
932 /*                                                                        */
933 /*    _nxe_rtsp_server_rtp_info_set                       PORTABLE C      */
934 /*                                                           6.3.0        */
935 /*  AUTHOR                                                                */
936 /*                                                                        */
937 /*    Wenhui Xie, Microsoft Corporation                                   */
938 /*                                                                        */
939 /*  DESCRIPTION                                                           */
940 /*                                                                        */
941 /*    This function checks for errors in RTP-Info set function call.      */
942 /*                                                                        */
943 /*  INPUT                                                                 */
944 /*                                                                        */
945 /*    rtsp_client_ptr                       Pointer to RTSP client        */
946 /*    track_id                              The track ID of the media     */
947 /*    track_id_len                          The length of the track ID    */
948 /*    rtp_seq                               The RTP sequence number       */
949 /*    rtp_time                              The RTP timestamp             */
950 /*                                                                        */
951 /*  OUTPUT                                                                */
952 /*                                                                        */
953 /*    status                                Completion status             */
954 /*                                                                        */
955 /*  CALLS                                                                 */
956 /*                                                                        */
957 /*    _nx_rtsp_server_rtp_info_set          Set RTP-Info in response      */
958 /*                                                                        */
959 /*  CALLED BY                                                             */
960 /*                                                                        */
961 /*    Application Code                                                    */
962 /*                                                                        */
963 /*  RELEASE HISTORY                                                       */
964 /*                                                                        */
965 /*    DATE              NAME                      DESCRIPTION             */
966 /*                                                                        */
967 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
968 /*                                                                        */
969 /**************************************************************************/
_nxe_rtsp_server_rtp_info_set(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * track_id,UINT track_id_len,UINT rtp_seq,UINT rtp_time)970 UINT _nxe_rtsp_server_rtp_info_set(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *track_id, UINT track_id_len, UINT rtp_seq, UINT rtp_time)
971 {
972 UINT       status;
973 
974 
975     /* Check for invalid input pointers.  */
976     if ((rtsp_client_ptr == NX_NULL) || (track_id == NX_NULL) || (track_id_len == 0) ||
977         (rtsp_client_ptr -> nx_rtsp_client_server_ptr == NX_NULL) ||
978         (rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
979     {
980         return(NX_PTR_ERROR);
981     }
982 
983     /* Call actual RTP-Info set function.  */
984     status = _nx_rtsp_server_rtp_info_set(rtsp_client_ptr, track_id, track_id_len, rtp_seq, rtp_time);
985 
986     /* Return status.  */
987     return(status);
988 }
989 
990 /**************************************************************************/
991 /*                                                                        */
992 /*  FUNCTION                                               RELEASE        */
993 /*                                                                        */
994 /*    _nx_rtsp_server_rtp_info_set                        PORTABLE C      */
995 /*                                                           6.3.0        */
996 /*  AUTHOR                                                                */
997 /*                                                                        */
998 /*    Wenhui Xie, Microsoft Corporation                                   */
999 /*                                                                        */
1000 /*  DESCRIPTION                                                           */
1001 /*                                                                        */
1002 /*    This function sets the RTP-Info to the response packet. This        */
1003 /*    function can only be called in PLAY callback function.              */
1004 /*                                                                        */
1005 /*  INPUT                                                                 */
1006 /*                                                                        */
1007 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1008 /*    track_id                              The track ID of the media     */
1009 /*    track_id_len                          The length of the track ID    */
1010 /*    rtp_seq                               The RTP sequence number       */
1011 /*    rtp_time                              The RTP timestamp             */
1012 /*                                                                        */
1013 /*  OUTPUT                                                                */
1014 /*                                                                        */
1015 /*    status                                Completion status             */
1016 /*                                                                        */
1017 /*  CALLS                                                                 */
1018 /*                                                                        */
1019 /*    nx_packet_data_append                 Append packet data            */
1020 /*    _nx_utility_uint_to_string            Convert integer to string     */
1021 /*                                                                        */
1022 /*  CALLED BY                                                             */
1023 /*                                                                        */
1024 /*    Application Code                                                    */
1025 /*                                                                        */
1026 /*  RELEASE HISTORY                                                       */
1027 /*                                                                        */
1028 /*    DATE              NAME                      DESCRIPTION             */
1029 /*                                                                        */
1030 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1031 /*                                                                        */
1032 /**************************************************************************/
_nx_rtsp_server_rtp_info_set(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * track_id,UINT track_id_len,UINT rtp_seq,UINT rtp_time)1033 UINT _nx_rtsp_server_rtp_info_set(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *track_id, UINT track_id_len, UINT rtp_seq, UINT rtp_time)
1034 {
1035 UINT       status;
1036 CHAR       temp_buffer[11];
1037 UINT       temp_length;
1038 NX_PACKET *response_packet_ptr = rtsp_client_ptr -> nx_rtsp_client_response_packet;
1039 
1040 
1041     /* Check if the packet is valid.  */
1042     if (!response_packet_ptr)
1043     {
1044         return(NX_RTSP_SERVER_NO_PACKET);
1045     }
1046 
1047     /* Check the request method.  */
1048     if ((!rtsp_client_ptr -> nx_rtsp_client_request_ptr) ||
1049         rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_method != NX_RTSP_METHOD_PLAY)
1050     {
1051         return(NX_RTSP_SERVER_INVALID_REQUEST);
1052     }
1053 
1054     /* Add "RTP-Info" header.  */
1055     status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("url="),
1056                                    rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1057     status += nx_packet_data_append(response_packet_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length,
1058                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1059     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("/"),
1060                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1061     status += nx_packet_data_append(response_packet_ptr, track_id, track_id_len,
1062                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1063     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";seq="),
1064                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1065     temp_length = _nx_utility_uint_to_string(rtp_seq, 10, temp_buffer, sizeof(temp_buffer));
1066     status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length,
1067                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1068     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";rtptime="),
1069                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1070     temp_length = _nx_utility_uint_to_string(rtp_time, 10, temp_buffer, sizeof(temp_buffer));
1071     status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length,
1072                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1073     status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(","),
1074                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
1075 
1076     return(status);
1077 }
1078 
1079 /**************************************************************************/
1080 /*                                                                        */
1081 /*  FUNCTION                                               RELEASE        */
1082 /*                                                                        */
1083 /*    _nxe_rtsp_server_range_npt_set                      PORTABLE C      */
1084 /*                                                           6.3.0        */
1085 /*  AUTHOR                                                                */
1086 /*                                                                        */
1087 /*    Wenhui Xie, Microsoft Corporation                                   */
1088 /*                                                                        */
1089 /*  DESCRIPTION                                                           */
1090 /*                                                                        */
1091 /*    This function checks for errors in NPT set function call.           */
1092 /*                                                                        */
1093 /*  INPUT                                                                 */
1094 /*                                                                        */
1095 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1096 /*    npt_start                             The NPT start time in         */
1097 /*                                            milliseconds                */
1098 /*    npt_end                               The NPT end time in           */
1099 /*                                            milliseconds                */
1100 /*                                                                        */
1101 /*  OUTPUT                                                                */
1102 /*                                                                        */
1103 /*    status                                Completion status             */
1104 /*                                                                        */
1105 /*  CALLS                                                                 */
1106 /*                                                                        */
1107 /*    _nx_rtsp_server_range_npt_set         Set NPT start and end time    */
1108 /*                                                                        */
1109 /*  CALLED BY                                                             */
1110 /*                                                                        */
1111 /*    Application Code                                                    */
1112 /*                                                                        */
1113 /*  RELEASE HISTORY                                                       */
1114 /*                                                                        */
1115 /*    DATE              NAME                      DESCRIPTION             */
1116 /*                                                                        */
1117 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1118 /*                                                                        */
1119 /**************************************************************************/
_nxe_rtsp_server_range_npt_set(NX_RTSP_CLIENT * rtsp_client_ptr,UINT npt_start,UINT npt_end)1120 UINT _nxe_rtsp_server_range_npt_set(NX_RTSP_CLIENT *rtsp_client_ptr, UINT npt_start, UINT npt_end)
1121 {
1122 UINT       status;
1123 
1124 
1125     /* Check for invalid input pointers.  */
1126     if ((rtsp_client_ptr == NX_NULL) || (rtsp_client_ptr -> nx_rtsp_client_server_ptr == NX_NULL) ||
1127         (rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1128     {
1129         return(NX_PTR_ERROR);
1130     }
1131 
1132     /* Call actual NPT set function.  */
1133     status = _nx_rtsp_server_range_npt_set(rtsp_client_ptr, npt_start, npt_end);
1134 
1135     /* Return status.  */
1136     return(status);
1137 }
1138 
1139 /**************************************************************************/
1140 /*                                                                        */
1141 /*  FUNCTION                                               RELEASE        */
1142 /*                                                                        */
1143 /*    _nx_rtsp_server_range_npt_set                       PORTABLE C      */
1144 /*                                                           6.3.0        */
1145 /*  AUTHOR                                                                */
1146 /*                                                                        */
1147 /*    Wenhui Xie, Microsoft Corporation                                   */
1148 /*                                                                        */
1149 /*  DESCRIPTION                                                           */
1150 /*                                                                        */
1151 /*    This function sets the NPT start and end time in Range field. This  */
1152 /*    function can only be called in PLAY and PAUSE callback function.    */
1153 /*                                                                        */
1154 /*  INPUT                                                                 */
1155 /*                                                                        */
1156 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1157 /*    npt_start                             The NPT start time in         */
1158 /*                                            milliseconds                */
1159 /*    npt_end                               The NPT end time in           */
1160 /*                                            milliseconds                */
1161 /*                                                                        */
1162 /*  OUTPUT                                                                */
1163 /*                                                                        */
1164 /*    status                                Completion status             */
1165 /*                                                                        */
1166 /*  CALLS                                                                 */
1167 /*                                                                        */
1168 /*    None                                                                */
1169 /*                                                                        */
1170 /*  CALLED BY                                                             */
1171 /*                                                                        */
1172 /*    Application Code                                                    */
1173 /*                                                                        */
1174 /*  RELEASE HISTORY                                                       */
1175 /*                                                                        */
1176 /*    DATE              NAME                      DESCRIPTION             */
1177 /*                                                                        */
1178 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1179 /*                                                                        */
1180 /**************************************************************************/
_nx_rtsp_server_range_npt_set(NX_RTSP_CLIENT * rtsp_client_ptr,UINT npt_start,UINT npt_end)1181 UINT _nx_rtsp_server_range_npt_set(NX_RTSP_CLIENT *rtsp_client_ptr, UINT npt_start, UINT npt_end)
1182 {
1183 
1184     /* Check the request method.  */
1185     if ((!rtsp_client_ptr -> nx_rtsp_client_request_ptr) ||
1186         ((rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_method != NX_RTSP_METHOD_PLAY) &&
1187          (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_method != NX_RTSP_METHOD_PAUSE)))
1188     {
1189         return(NX_RTSP_SERVER_INVALID_REQUEST);
1190     }
1191 
1192     /* Check start and end time.  */
1193     if (npt_end < npt_start)
1194     {
1195         return(NX_RTSP_SERVER_INVALID_PARAMETER);
1196     }
1197 
1198     /* Set the NPT start and end time in milliseconds.  */
1199     rtsp_client_ptr -> nx_rtsp_client_npt_start = npt_start;
1200     rtsp_client_ptr -> nx_rtsp_client_npt_end = npt_end;
1201 
1202     return(NX_SUCCESS);
1203 }
1204 /**************************************************************************/
1205 /*                                                                        */
1206 /*  FUNCTION                                               RELEASE        */
1207 /*                                                                        */
1208 /*    _nxe_rtsp_server_error_response_send                PORTABLE C      */
1209 /*                                                           6.3.0        */
1210 /*  AUTHOR                                                                */
1211 /*                                                                        */
1212 /*    Wenhui Xie, Microsoft Corporation                                   */
1213 /*                                                                        */
1214 /*  DESCRIPTION                                                           */
1215 /*                                                                        */
1216 /*    This function checks for errors in error response send call.        */
1217 /*                                                                        */
1218 /*  INPUT                                                                 */
1219 /*                                                                        */
1220 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1221 /*    status_code                           The status code of response   */
1222 /*                                                                        */
1223 /*  OUTPUT                                                                */
1224 /*                                                                        */
1225 /*    status                                Completion status             */
1226 /*                                                                        */
1227 /*  CALLS                                                                 */
1228 /*                                                                        */
1229 /*    _nx_rtsp_server_error_response_send   Send error response           */
1230 /*                                                                        */
1231 /*  CALLED BY                                                             */
1232 /*                                                                        */
1233 /*    Application Code                                                    */
1234 /*                                                                        */
1235 /*  RELEASE HISTORY                                                       */
1236 /*                                                                        */
1237 /*    DATE              NAME                      DESCRIPTION             */
1238 /*                                                                        */
1239 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1240 /*                                                                        */
1241 /**************************************************************************/
_nxe_rtsp_server_error_response_send(NX_RTSP_CLIENT * rtsp_client_ptr,UINT status_code)1242 UINT _nxe_rtsp_server_error_response_send(NX_RTSP_CLIENT *rtsp_client_ptr, UINT status_code)
1243 {
1244 UINT       status;
1245 
1246 
1247     /* Check for invalid input pointers.  */
1248     if ((rtsp_client_ptr == NX_NULL) || (rtsp_client_ptr -> nx_rtsp_client_server_ptr == NX_NULL) ||
1249         (rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1250     {
1251         return(NX_PTR_ERROR);
1252     }
1253 
1254     /* Call actual error response send function.  */
1255     status = _nx_rtsp_server_error_response_send(rtsp_client_ptr, status_code);
1256 
1257     /* Return status.  */
1258     return(status);
1259 }
1260 
1261 /**************************************************************************/
1262 /*                                                                        */
1263 /*  FUNCTION                                               RELEASE        */
1264 /*                                                                        */
1265 /*    _nx_rtsp_server_error_response_send                 PORTABLE C      */
1266 /*                                                           6.3.0        */
1267 /*  AUTHOR                                                                */
1268 /*                                                                        */
1269 /*    Wenhui Xie, Microsoft Corporation                                   */
1270 /*                                                                        */
1271 /*  DESCRIPTION                                                           */
1272 /*                                                                        */
1273 /*    This function sends the error response packet.                      */
1274 /*                                                                        */
1275 /*  INPUT                                                                 */
1276 /*                                                                        */
1277 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1278 /*    status_code                           The status code of response   */
1279 /*                                                                        */
1280 /*  OUTPUT                                                                */
1281 /*                                                                        */
1282 /*    status                                Completion status             */
1283 /*                                                                        */
1284 /*  CALLS                                                                 */
1285 /*                                                                        */
1286 /*    nx_packet_release                     Release the packet            */
1287 /*    nx_packet_data_append                 Append packet data            */
1288 /*    _nx_utility_uint_to_string            Convert integer to string     */
1289 /*    _nx_utility_string_length_check       Check string length           */
1290 /*    nx_tcp_socket_send                    Send TCP packet               */
1291 /*                                                                        */
1292 /*  CALLED BY                                                             */
1293 /*                                                                        */
1294 /*    Application Code                                                    */
1295 /*                                                                        */
1296 /*  RELEASE HISTORY                                                       */
1297 /*                                                                        */
1298 /*    DATE              NAME                      DESCRIPTION             */
1299 /*                                                                        */
1300 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1301 /*                                                                        */
1302 /**************************************************************************/
_nx_rtsp_server_error_response_send(NX_RTSP_CLIENT * rtsp_client_ptr,UINT status_code)1303 UINT _nx_rtsp_server_error_response_send(NX_RTSP_CLIENT *rtsp_client_ptr, UINT status_code)
1304 {
1305 UINT       status;
1306 UINT       i;
1307 CHAR       temp_buffer[11];
1308 UINT       temp_length;
1309 NX_PACKET *response_packet_ptr = rtsp_client_ptr -> nx_rtsp_client_response_packet;
1310 NX_PACKET_POOL *pool_ptr = rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool;
1311 
1312 
1313     if (!response_packet_ptr)
1314     {
1315         return(NX_RTSP_SERVER_NO_PACKET);
1316     }
1317 
1318     /* Loop to find the corresponding description.  */
1319     for (i = 0; nx_rtsp_server_response_description_table[i].nx_rtsp_response_code != NX_NULL; i++)
1320     {
1321         if (nx_rtsp_server_response_description_table[i].nx_rtsp_response_code == status_code)
1322         {
1323             break;
1324         }
1325     }
1326 
1327     if (nx_rtsp_server_response_description_table[i].nx_rtsp_response_code == NX_NULL)
1328     {
1329         return(NX_RTSP_SERVER_INVALID_PARAMETER);
1330     }
1331 
1332 #ifndef NX_DISABLE_PACKET_CHAIN
1333     /* Reuse the response packet to append the error message.
1334        If user has already appended data to this packet and there are packets chained,
1335        remove and release the chained packets. */
1336     if (response_packet_ptr -> nx_packet_next)
1337     {
1338         nx_packet_release(response_packet_ptr -> nx_packet_next);
1339         response_packet_ptr -> nx_packet_next = NX_NULL;
1340         response_packet_ptr -> nx_packet_last = NX_NULL;
1341     }
1342 #endif /* NX_DISABLE_PACKET_CHAIN */
1343 
1344     /* Reset the packet.  */
1345     response_packet_ptr -> nx_packet_append_ptr = response_packet_ptr -> nx_packet_prepend_ptr;
1346     response_packet_ptr -> nx_packet_length = 0;
1347 
1348     /* Add version.  */
1349     status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(NX_RTSP_VERSION_STRING),
1350                                    pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1351     status += nx_packet_data_append(response_packet_ptr, " ", 1, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1352 
1353     /* Add status code.  */
1354     temp_length = _nx_utility_uint_to_string(status_code, 10, temp_buffer, sizeof(temp_buffer));
1355     status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1356     status += nx_packet_data_append(response_packet_ptr, " ", 1, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1357     _nx_utility_string_length_check(nx_rtsp_server_response_description_table[i].nx_rtsp_response_description, &temp_length, NX_MAX_STRING_LENGTH);
1358     status += nx_packet_data_append(response_packet_ptr, nx_rtsp_server_response_description_table[i].nx_rtsp_response_description,
1359                                     temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1360     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1361 
1362     /* Add "CSeq" header.  */
1363     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("CSeq: "), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1364     temp_length = _nx_utility_uint_to_string(rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_sequence_number, 10, temp_buffer, sizeof(temp_buffer));
1365     status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1366     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1367 
1368     /* Add "Server" header.  */
1369     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("Server: "), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1370     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_name,
1371                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_name_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1372     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n\r\n"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
1373 
1374     if (status == NX_SUCCESS)
1375     {
1376 
1377         /* Send the response message back.  */
1378         status =  nx_tcp_socket_send(&rtsp_client_ptr -> nx_rtsp_client_socket, response_packet_ptr, NX_RTSP_SERVER_SEND_TIMEOUT);
1379     }
1380 
1381     /* Determine if the send was unsuccessful.  */
1382     if (status)
1383     {
1384 
1385         /* Release the packet.  */
1386         nx_packet_release(response_packet_ptr);
1387     }
1388 
1389     /* Clear the response packet pointer.  */
1390     rtsp_client_ptr -> nx_rtsp_client_response_packet = NX_NULL;
1391 
1392     return(status);
1393 }
1394 
1395 /**************************************************************************/
1396 /*                                                                        */
1397 /*  FUNCTION                                               RELEASE        */
1398 /*                                                                        */
1399 /*    _nxe_rtsp_server_keepalive_update                   PORTABLE C      */
1400 /*                                                           6.3.0        */
1401 /*  AUTHOR                                                                */
1402 /*                                                                        */
1403 /*    Wenhui Xie, Microsoft Corporation                                   */
1404 /*                                                                        */
1405 /*  DESCRIPTION                                                           */
1406 /*                                                                        */
1407 /*    This function checks for errors in keepalive update function call.  */
1408 /*                                                                        */
1409 /*  INPUT                                                                 */
1410 /*                                                                        */
1411 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1412 /*                                                                        */
1413 /*  OUTPUT                                                                */
1414 /*                                                                        */
1415 /*    status                                Completion status             */
1416 /*                                                                        */
1417 /*  CALLS                                                                 */
1418 /*                                                                        */
1419 /*    _nx_rtsp_server_keepalive_update      Update the timeout timer      */
1420 /*                                                                        */
1421 /*  CALLED BY                                                             */
1422 /*                                                                        */
1423 /*    Application Code                                                    */
1424 /*                                                                        */
1425 /*  RELEASE HISTORY                                                       */
1426 /*                                                                        */
1427 /*    DATE              NAME                      DESCRIPTION             */
1428 /*                                                                        */
1429 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1430 /*                                                                        */
1431 /**************************************************************************/
_nxe_rtsp_server_keepalive_update(NX_RTSP_CLIENT * rtsp_client_ptr)1432 UINT _nxe_rtsp_server_keepalive_update(NX_RTSP_CLIENT *rtsp_client_ptr)
1433 {
1434 UINT       status;
1435 
1436 
1437     /* Check for invalid input pointers.  */
1438     if ((rtsp_client_ptr == NX_NULL) || (rtsp_client_ptr -> nx_rtsp_client_server_ptr == NX_NULL) ||
1439         (rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1440     {
1441         return(NX_PTR_ERROR);
1442     }
1443 
1444     /* Call actual keep-alive update function.  */
1445     status = _nx_rtsp_server_keepalive_update(rtsp_client_ptr);
1446 
1447     /* Return status.  */
1448     return(status);
1449 }
1450 
1451 /**************************************************************************/
1452 /*                                                                        */
1453 /*  FUNCTION                                               RELEASE        */
1454 /*                                                                        */
1455 /*    _nx_rtsp_server_keepalive_update                    PORTABLE C      */
1456 /*                                                           6.3.0        */
1457 /*  AUTHOR                                                                */
1458 /*                                                                        */
1459 /*    Wenhui Xie, Microsoft Corporation                                   */
1460 /*                                                                        */
1461 /*  DESCRIPTION                                                           */
1462 /*                                                                        */
1463 /*    This function updates the timeout timer of the client. If RTP is    */
1464 /*    used for media transport, RTCP is used to show liveness of client.  */
1465 /*                                                                        */
1466 /*  INPUT                                                                 */
1467 /*                                                                        */
1468 /*    rtsp_client_ptr                       Pointer to RTSP client        */
1469 /*                                                                        */
1470 /*  OUTPUT                                                                */
1471 /*                                                                        */
1472 /*    status                                Completion status             */
1473 /*                                                                        */
1474 /*  CALLS                                                                 */
1475 /*                                                                        */
1476 /*    None                                                                */
1477 /*                                                                        */
1478 /*  CALLED BY                                                             */
1479 /*                                                                        */
1480 /*    Application Code                                                    */
1481 /*                                                                        */
1482 /*  RELEASE HISTORY                                                       */
1483 /*                                                                        */
1484 /*    DATE              NAME                      DESCRIPTION             */
1485 /*                                                                        */
1486 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1487 /*                                                                        */
1488 /**************************************************************************/
_nx_rtsp_server_keepalive_update(NX_RTSP_CLIENT * rtsp_client_ptr)1489 UINT _nx_rtsp_server_keepalive_update(NX_RTSP_CLIENT *rtsp_client_ptr)
1490 {
1491 
1492     /* Reset the client request activity timeout.  */
1493     if (rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout)
1494     {
1495         rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout = NX_RTSP_SERVER_ACTIVITY_TIMEOUT;
1496     }
1497 
1498     return(NX_SUCCESS);
1499 }
1500 
1501 /**************************************************************************/
1502 /*                                                                        */
1503 /*  FUNCTION                                               RELEASE        */
1504 /*                                                                        */
1505 /*    _nxe_rtsp_server_describe_callback_set              PORTABLE C      */
1506 /*                                                           6.3.0        */
1507 /*  AUTHOR                                                                */
1508 /*                                                                        */
1509 /*    Wenhui Xie, Microsoft Corporation                                   */
1510 /*                                                                        */
1511 /*  DESCRIPTION                                                           */
1512 /*                                                                        */
1513 /*    This function checks for errors in DESCRIBE callback set.           */
1514 /*                                                                        */
1515 /*  INPUT                                                                 */
1516 /*                                                                        */
1517 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1518 /*    callback                              Callback of DESCRIBE request  */
1519 /*                                                                        */
1520 /*  OUTPUT                                                                */
1521 /*                                                                        */
1522 /*    status                                Completion status             */
1523 /*                                                                        */
1524 /*  CALLS                                                                 */
1525 /*                                                                        */
1526 /*    _nx_rtsp_server_describe_callback_set Set DESCRIBE callback         */
1527 /*                                                                        */
1528 /*  CALLED BY                                                             */
1529 /*                                                                        */
1530 /*    Application Code                                                    */
1531 /*                                                                        */
1532 /*  RELEASE HISTORY                                                       */
1533 /*                                                                        */
1534 /*    DATE              NAME                      DESCRIPTION             */
1535 /*                                                                        */
1536 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1537 /*                                                                        */
1538 /**************************************************************************/
_nxe_rtsp_server_describe_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length))1539 UINT _nxe_rtsp_server_describe_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1540                                             UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length))
1541 {
1542 UINT       status;
1543 
1544 
1545     /* Check for invalid input pointers.  */
1546     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
1547          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1548     {
1549         return(NX_PTR_ERROR);
1550     }
1551 
1552     /* Call actual DESCRIBE callback set function.  */
1553     status = _nx_rtsp_server_describe_callback_set(rtsp_server_ptr, callback);
1554 
1555     /* Return status.  */
1556     return(status);
1557 }
1558 
1559 /**************************************************************************/
1560 /*                                                                        */
1561 /*  FUNCTION                                               RELEASE        */
1562 /*                                                                        */
1563 /*    _nx_rtsp_server_describe_callback_set               PORTABLE C      */
1564 /*                                                           6.3.0        */
1565 /*  AUTHOR                                                                */
1566 /*                                                                        */
1567 /*    Wenhui Xie, Microsoft Corporation                                   */
1568 /*                                                                        */
1569 /*  DESCRIPTION                                                           */
1570 /*                                                                        */
1571 /*    This function installs callback function for DESCRIBE request.      */
1572 /*                                                                        */
1573 /*  INPUT                                                                 */
1574 /*                                                                        */
1575 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1576 /*    callback                              Callback of DESCRIBE request  */
1577 /*                                                                        */
1578 /*  OUTPUT                                                                */
1579 /*                                                                        */
1580 /*    status                                Completion status             */
1581 /*                                                                        */
1582 /*  CALLS                                                                 */
1583 /*                                                                        */
1584 /*    None                                                                */
1585 /*                                                                        */
1586 /*  CALLED BY                                                             */
1587 /*                                                                        */
1588 /*    Application Code                                                    */
1589 /*                                                                        */
1590 /*  RELEASE HISTORY                                                       */
1591 /*                                                                        */
1592 /*    DATE              NAME                      DESCRIPTION             */
1593 /*                                                                        */
1594 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1595 /*                                                                        */
1596 /**************************************************************************/
_nx_rtsp_server_describe_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length))1597 UINT _nx_rtsp_server_describe_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1598                                            UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length))
1599 {
1600 
1601     /* Set callback for DESCRIBE method.  */
1602     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_describe_callback = callback;
1603 
1604     return(NX_SUCCESS);
1605 }
1606 
1607 /**************************************************************************/
1608 /*                                                                        */
1609 /*  FUNCTION                                               RELEASE        */
1610 /*                                                                        */
1611 /*    _nxe_rtsp_server_setup_callback_set                 PORTABLE C      */
1612 /*                                                           6.3.0        */
1613 /*  AUTHOR                                                                */
1614 /*                                                                        */
1615 /*    Wenhui Xie, Microsoft Corporation                                   */
1616 /*                                                                        */
1617 /*  DESCRIPTION                                                           */
1618 /*                                                                        */
1619 /*    This function checks for errors in SETUP callback set.              */
1620 /*                                                                        */
1621 /*  INPUT                                                                 */
1622 /*                                                                        */
1623 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1624 /*    callback                              Callback of SETUP request     */
1625 /*                                                                        */
1626 /*  OUTPUT                                                                */
1627 /*                                                                        */
1628 /*    status                                Completion status             */
1629 /*                                                                        */
1630 /*  CALLS                                                                 */
1631 /*                                                                        */
1632 /*    _nx_rtsp_server_setup_callback_set    Set SETUP callback            */
1633 /*                                                                        */
1634 /*  CALLED BY                                                             */
1635 /*                                                                        */
1636 /*    Application Code                                                    */
1637 /*                                                                        */
1638 /*  RELEASE HISTORY                                                       */
1639 /*                                                                        */
1640 /*    DATE              NAME                      DESCRIPTION             */
1641 /*                                                                        */
1642 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1643 /*                                                                        */
1644 /**************************************************************************/
_nxe_rtsp_server_setup_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,NX_RTSP_TRANSPORT * transport_ptr))1645 UINT _nxe_rtsp_server_setup_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1646                                          UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr))
1647 {
1648 UINT       status;
1649 
1650 
1651     /* Check for invalid input pointers.  */
1652     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
1653          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1654     {
1655         return(NX_PTR_ERROR);
1656     }
1657 
1658     /* Call actual SETUP callback set function.  */
1659     status = _nx_rtsp_server_setup_callback_set(rtsp_server_ptr, callback);
1660 
1661     /* Return status.  */
1662     return(status);
1663 }
1664 
1665 /**************************************************************************/
1666 /*                                                                        */
1667 /*  FUNCTION                                               RELEASE        */
1668 /*                                                                        */
1669 /*    _nx_rtsp_server_setup_callback_set                  PORTABLE C      */
1670 /*                                                           6.3.0        */
1671 /*  AUTHOR                                                                */
1672 /*                                                                        */
1673 /*    Wenhui Xie, Microsoft Corporation                                   */
1674 /*                                                                        */
1675 /*  DESCRIPTION                                                           */
1676 /*                                                                        */
1677 /*    This function installs callback function for SETUP request.         */
1678 /*                                                                        */
1679 /*  INPUT                                                                 */
1680 /*                                                                        */
1681 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1682 /*    callback                              Callback of SETUP request     */
1683 /*                                                                        */
1684 /*  OUTPUT                                                                */
1685 /*                                                                        */
1686 /*    status                                Completion status             */
1687 /*                                                                        */
1688 /*  CALLS                                                                 */
1689 /*                                                                        */
1690 /*    None                                                                */
1691 /*                                                                        */
1692 /*  CALLED BY                                                             */
1693 /*                                                                        */
1694 /*    Application Code                                                    */
1695 /*                                                                        */
1696 /*  RELEASE HISTORY                                                       */
1697 /*                                                                        */
1698 /*    DATE              NAME                      DESCRIPTION             */
1699 /*                                                                        */
1700 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1701 /*                                                                        */
1702 /**************************************************************************/
_nx_rtsp_server_setup_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,NX_RTSP_TRANSPORT * transport_ptr))1703 UINT _nx_rtsp_server_setup_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1704                                         UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr))
1705 {
1706 
1707     /* Set callback for SETUP method.  */
1708     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_setup_callback = callback;
1709 
1710     return(NX_SUCCESS);
1711 }
1712 
1713 /**************************************************************************/
1714 /*                                                                        */
1715 /*  FUNCTION                                               RELEASE        */
1716 /*                                                                        */
1717 /*    _nxe_rtsp_server_play_callback_set                  PORTABLE C      */
1718 /*                                                           6.3.0        */
1719 /*  AUTHOR                                                                */
1720 /*                                                                        */
1721 /*    Wenhui Xie, Microsoft Corporation                                   */
1722 /*                                                                        */
1723 /*  DESCRIPTION                                                           */
1724 /*                                                                        */
1725 /*    This function checks for errors in PLAY callback set.               */
1726 /*                                                                        */
1727 /*  INPUT                                                                 */
1728 /*                                                                        */
1729 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1730 /*    callback                              Callback of PLAY request      */
1731 /*                                                                        */
1732 /*  OUTPUT                                                                */
1733 /*                                                                        */
1734 /*    status                                Completion status             */
1735 /*                                                                        */
1736 /*  CALLS                                                                 */
1737 /*                                                                        */
1738 /*    _nx_rtsp_server_play_callback_set     Set PLAY callback             */
1739 /*                                                                        */
1740 /*  CALLED BY                                                             */
1741 /*                                                                        */
1742 /*    Application Code                                                    */
1743 /*                                                                        */
1744 /*  RELEASE HISTORY                                                       */
1745 /*                                                                        */
1746 /*    DATE              NAME                      DESCRIPTION             */
1747 /*                                                                        */
1748 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1749 /*                                                                        */
1750 /**************************************************************************/
_nxe_rtsp_server_play_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length))1751 UINT _nxe_rtsp_server_play_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1752                                         UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length))
1753 {
1754 UINT       status;
1755 
1756 
1757     /* Check for invalid input pointers.  */
1758     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
1759          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1760     {
1761         return(NX_PTR_ERROR);
1762     }
1763 
1764     /* Call actual PLAY callback set function.  */
1765     status = _nx_rtsp_server_play_callback_set(rtsp_server_ptr, callback);
1766 
1767     /* Return status.  */
1768     return(status);
1769 }
1770 
1771 /**************************************************************************/
1772 /*                                                                        */
1773 /*  FUNCTION                                               RELEASE        */
1774 /*                                                                        */
1775 /*    _nx_rtsp_server_play_callback_set                   PORTABLE C      */
1776 /*                                                           6.3.0        */
1777 /*  AUTHOR                                                                */
1778 /*                                                                        */
1779 /*    Wenhui Xie, Microsoft Corporation                                   */
1780 /*                                                                        */
1781 /*  DESCRIPTION                                                           */
1782 /*                                                                        */
1783 /*    This function installs callback function for PLAY request.          */
1784 /*                                                                        */
1785 /*  INPUT                                                                 */
1786 /*                                                                        */
1787 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1788 /*    callback                              Callback of PLAY request      */
1789 /*                                                                        */
1790 /*  OUTPUT                                                                */
1791 /*                                                                        */
1792 /*    status                                Completion status             */
1793 /*                                                                        */
1794 /*  CALLS                                                                 */
1795 /*                                                                        */
1796 /*    None                                                                */
1797 /*                                                                        */
1798 /*  CALLED BY                                                             */
1799 /*                                                                        */
1800 /*    Application Code                                                    */
1801 /*                                                                        */
1802 /*  RELEASE HISTORY                                                       */
1803 /*                                                                        */
1804 /*    DATE              NAME                      DESCRIPTION             */
1805 /*                                                                        */
1806 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1807 /*                                                                        */
1808 /**************************************************************************/
_nx_rtsp_server_play_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length))1809 UINT _nx_rtsp_server_play_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1810                                        UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length))
1811 {
1812 
1813     /* Set callback for PLAY method.  */
1814     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_play_callback = callback;
1815 
1816     return(NX_SUCCESS);
1817 }
1818 
1819 /**************************************************************************/
1820 /*                                                                        */
1821 /*  FUNCTION                                               RELEASE        */
1822 /*                                                                        */
1823 /*    _nxe_rtsp_server_teardown_callback_set              PORTABLE C      */
1824 /*                                                           6.3.0        */
1825 /*  AUTHOR                                                                */
1826 /*                                                                        */
1827 /*    Wenhui Xie, Microsoft Corporation                                   */
1828 /*                                                                        */
1829 /*  DESCRIPTION                                                           */
1830 /*                                                                        */
1831 /*    This function checks for errors in TEARDOWN callback set.           */
1832 /*                                                                        */
1833 /*  INPUT                                                                 */
1834 /*                                                                        */
1835 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1836 /*    callback                              Callback of TEARDOWN request  */
1837 /*                                                                        */
1838 /*  OUTPUT                                                                */
1839 /*                                                                        */
1840 /*    status                                Completion status             */
1841 /*                                                                        */
1842 /*  CALLS                                                                 */
1843 /*                                                                        */
1844 /*    _nx_rtsp_server_teardown_callback_set Set TEARDOWN callback         */
1845 /*                                                                        */
1846 /*  CALLED BY                                                             */
1847 /*                                                                        */
1848 /*    Application Code                                                    */
1849 /*                                                                        */
1850 /*  RELEASE HISTORY                                                       */
1851 /*                                                                        */
1852 /*    DATE              NAME                      DESCRIPTION             */
1853 /*                                                                        */
1854 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1855 /*                                                                        */
1856 /**************************************************************************/
_nxe_rtsp_server_teardown_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length))1857 UINT _nxe_rtsp_server_teardown_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1858                                             UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length))
1859 {
1860 UINT       status;
1861 
1862 
1863     /* Check for invalid input pointers.  */
1864     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
1865          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1866     {
1867         return(NX_PTR_ERROR);
1868     }
1869 
1870     /* Call actual TEARDOWN callback set function.  */
1871     status = _nx_rtsp_server_teardown_callback_set(rtsp_server_ptr, callback);
1872 
1873     /* Return status.  */
1874     return(status);
1875 }
1876 
1877 /**************************************************************************/
1878 /*                                                                        */
1879 /*  FUNCTION                                               RELEASE        */
1880 /*                                                                        */
1881 /*    _nx_rtsp_server_teardown_callback_set               PORTABLE C      */
1882 /*                                                           6.3.0        */
1883 /*  AUTHOR                                                                */
1884 /*                                                                        */
1885 /*    Wenhui Xie, Microsoft Corporation                                   */
1886 /*                                                                        */
1887 /*  DESCRIPTION                                                           */
1888 /*                                                                        */
1889 /*    This function installs callback function for TEARDOWN request.      */
1890 /*                                                                        */
1891 /*  INPUT                                                                 */
1892 /*                                                                        */
1893 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1894 /*    callback                              Callback of TEARDOWN request  */
1895 /*                                                                        */
1896 /*  OUTPUT                                                                */
1897 /*                                                                        */
1898 /*    status                                Completion status             */
1899 /*                                                                        */
1900 /*  CALLS                                                                 */
1901 /*                                                                        */
1902 /*    None                                                                */
1903 /*                                                                        */
1904 /*  CALLED BY                                                             */
1905 /*                                                                        */
1906 /*    Application Code                                                    */
1907 /*                                                                        */
1908 /*  RELEASE HISTORY                                                       */
1909 /*                                                                        */
1910 /*    DATE              NAME                      DESCRIPTION             */
1911 /*                                                                        */
1912 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1913 /*                                                                        */
1914 /**************************************************************************/
_nx_rtsp_server_teardown_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length))1915 UINT _nx_rtsp_server_teardown_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1916                                            UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length))
1917 {
1918 
1919     /* Set callback for TEARDOWN method.  */
1920     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_teardown_callback = callback;
1921 
1922     return(NX_SUCCESS);
1923 }
1924 
1925 /**************************************************************************/
1926 /*                                                                        */
1927 /*  FUNCTION                                               RELEASE        */
1928 /*                                                                        */
1929 /*    _nxe_rtsp_server_pause_callback_set                 PORTABLE C      */
1930 /*                                                           6.3.0        */
1931 /*  AUTHOR                                                                */
1932 /*                                                                        */
1933 /*    Wenhui Xie, Microsoft Corporation                                   */
1934 /*                                                                        */
1935 /*  DESCRIPTION                                                           */
1936 /*                                                                        */
1937 /*    This function checks for errors in PAUSE callback set.              */
1938 /*                                                                        */
1939 /*  INPUT                                                                 */
1940 /*                                                                        */
1941 /*    rtsp_server_ptr                       Pointer to RTSP server        */
1942 /*    callback                              Callback of PAUSE request     */
1943 /*                                                                        */
1944 /*  OUTPUT                                                                */
1945 /*                                                                        */
1946 /*    status                                Completion status             */
1947 /*                                                                        */
1948 /*  CALLS                                                                 */
1949 /*                                                                        */
1950 /*    _nx_rtsp_server_pause_callback_set    Set PAUSE callback            */
1951 /*                                                                        */
1952 /*  CALLED BY                                                             */
1953 /*                                                                        */
1954 /*    Application Code                                                    */
1955 /*                                                                        */
1956 /*  RELEASE HISTORY                                                       */
1957 /*                                                                        */
1958 /*    DATE              NAME                      DESCRIPTION             */
1959 /*                                                                        */
1960 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
1961 /*                                                                        */
1962 /**************************************************************************/
_nxe_rtsp_server_pause_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length))1963 UINT _nxe_rtsp_server_pause_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
1964                                         UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length))
1965 {
1966 UINT       status;
1967 
1968 
1969     /* Check for invalid input pointers.  */
1970     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
1971          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
1972     {
1973         return(NX_PTR_ERROR);
1974     }
1975 
1976     /* Call actual PAUSE callback set function.  */
1977     status = _nx_rtsp_server_pause_callback_set(rtsp_server_ptr, callback);
1978 
1979     /* Return status.  */
1980     return(status);
1981 }
1982 
1983 /**************************************************************************/
1984 /*                                                                        */
1985 /*  FUNCTION                                               RELEASE        */
1986 /*                                                                        */
1987 /*    _nx_rtsp_server_pause_callback_set                  PORTABLE C      */
1988 /*                                                           6.3.0        */
1989 /*  AUTHOR                                                                */
1990 /*                                                                        */
1991 /*    Wenhui Xie, Microsoft Corporation                                   */
1992 /*                                                                        */
1993 /*  DESCRIPTION                                                           */
1994 /*                                                                        */
1995 /*    This function installs callback function for PAUSE request.         */
1996 /*                                                                        */
1997 /*  INPUT                                                                 */
1998 /*                                                                        */
1999 /*    rtsp_server_ptr                       Pointer to RTSP server        */
2000 /*    callback                              Callback of PAUSE request     */
2001 /*                                                                        */
2002 /*  OUTPUT                                                                */
2003 /*                                                                        */
2004 /*    status                                Completion status             */
2005 /*                                                                        */
2006 /*  CALLS                                                                 */
2007 /*                                                                        */
2008 /*    None                                                                */
2009 /*                                                                        */
2010 /*  CALLED BY                                                             */
2011 /*                                                                        */
2012 /*    Application Code                                                    */
2013 /*                                                                        */
2014 /*  RELEASE HISTORY                                                       */
2015 /*                                                                        */
2016 /*    DATE              NAME                      DESCRIPTION             */
2017 /*                                                                        */
2018 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2019 /*                                                                        */
2020 /**************************************************************************/
_nx_rtsp_server_pause_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * range_ptr,UINT range_length))2021 UINT _nx_rtsp_server_pause_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
2022                                         UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length))
2023 {
2024 
2025     /* Set callback for PAUSE method.  */
2026     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_pause_callback = callback;
2027 
2028     return(NX_SUCCESS);
2029 }
2030 
2031 /**************************************************************************/
2032 /*                                                                        */
2033 /*  FUNCTION                                               RELEASE        */
2034 /*                                                                        */
2035 /*    _nxe_rtsp_server_set_parameter_callback_set         PORTABLE C      */
2036 /*                                                           6.3.0        */
2037 /*  AUTHOR                                                                */
2038 /*                                                                        */
2039 /*    Wenhui Xie, Microsoft Corporation                                   */
2040 /*                                                                        */
2041 /*  DESCRIPTION                                                           */
2042 /*                                                                        */
2043 /*    This function checks for errors in SET_PARAMETER callback set.      */
2044 /*                                                                        */
2045 /*  INPUT                                                                 */
2046 /*                                                                        */
2047 /*    rtsp_server_ptr                       Pointer to RTSP server        */
2048 /*    callback                              Callback of SET_PARAMETER     */
2049 /*                                            request                     */
2050 /*                                                                        */
2051 /*  OUTPUT                                                                */
2052 /*                                                                        */
2053 /*    status                                Completion status             */
2054 /*                                                                        */
2055 /*  CALLS                                                                 */
2056 /*                                                                        */
2057 /*    _nx_rtsp_server_set_parameter_callback_set                          */
2058 /*                                          Set SET_PARAMETER callback    */
2059 /*                                                                        */
2060 /*  CALLED BY                                                             */
2061 /*                                                                        */
2062 /*    Application Code                                                    */
2063 /*                                                                        */
2064 /*  RELEASE HISTORY                                                       */
2065 /*                                                                        */
2066 /*    DATE              NAME                      DESCRIPTION             */
2067 /*                                                                        */
2068 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2069 /*                                                                        */
2070 /**************************************************************************/
_nxe_rtsp_server_set_parameter_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * parameter_ptr,ULONG parameter_length))2071 UINT _nxe_rtsp_server_set_parameter_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
2072                                                  UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length))
2073 {
2074 UINT       status;
2075 
2076 
2077     /* Check for invalid input pointers.  */
2078     if ((rtsp_server_ptr == NX_NULL) || (callback == NX_NULL) ||
2079          (rtsp_server_ptr -> nx_rtsp_server_id != NX_RTSP_SERVER_ID))
2080     {
2081         return(NX_PTR_ERROR);
2082     }
2083 
2084     /* Call actual SET_PARAMETER callback set function.  */
2085     status = _nx_rtsp_server_set_parameter_callback_set(rtsp_server_ptr, callback);
2086 
2087     /* Return status.  */
2088     return(status);
2089 }
2090 
2091 /**************************************************************************/
2092 /*                                                                        */
2093 /*  FUNCTION                                               RELEASE        */
2094 /*                                                                        */
2095 /*    _nx_rtsp_server_set_parameter_callback_set          PORTABLE C      */
2096 /*                                                           6.3.0        */
2097 /*  AUTHOR                                                                */
2098 /*                                                                        */
2099 /*    Wenhui Xie, Microsoft Corporation                                   */
2100 /*                                                                        */
2101 /*  DESCRIPTION                                                           */
2102 /*                                                                        */
2103 /*    This function installs callback function for SET_PARAMETER request. */
2104 /*                                                                        */
2105 /*  INPUT                                                                 */
2106 /*                                                                        */
2107 /*    rtsp_server_ptr                       Pointer to RTSP server        */
2108 /*    callback                              Callback of SET_PARAMETER     */
2109 /*                                            request                     */
2110 /*                                                                        */
2111 /*  OUTPUT                                                                */
2112 /*                                                                        */
2113 /*    status                                Completion status             */
2114 /*                                                                        */
2115 /*  CALLS                                                                 */
2116 /*                                                                        */
2117 /*    None                                                                */
2118 /*                                                                        */
2119 /*  CALLED BY                                                             */
2120 /*                                                                        */
2121 /*    Application Code                                                    */
2122 /*                                                                        */
2123 /*  RELEASE HISTORY                                                       */
2124 /*                                                                        */
2125 /*    DATE              NAME                      DESCRIPTION             */
2126 /*                                                                        */
2127 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2128 /*                                                                        */
2129 /**************************************************************************/
_nx_rtsp_server_set_parameter_callback_set(NX_RTSP_SERVER * rtsp_server_ptr,UINT (* callback)(NX_RTSP_CLIENT * rtsp_client_ptr,UCHAR * uri,UINT uri_length,UCHAR * parameter_ptr,ULONG parameter_length))2130 UINT _nx_rtsp_server_set_parameter_callback_set(NX_RTSP_SERVER *rtsp_server_ptr,
2131                                                 UINT (*callback)(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length))
2132 {
2133 
2134     /* Set callback for SET_PARAMETER method.  */
2135     rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_set_parameter_callback = callback;
2136 
2137     return(NX_SUCCESS);
2138 }
2139 
2140 /**************************************************************************/
2141 /*                                                                        */
2142 /*  FUNCTION                                               RELEASE        */
2143 /*                                                                        */
2144 /*    _nx_rtsp_server_thread_entry                        PORTABLE C      */
2145 /*                                                           6.3.0        */
2146 /*  AUTHOR                                                                */
2147 /*                                                                        */
2148 /*    Wenhui Xie, Microsoft Corporation                                   */
2149 /*                                                                        */
2150 /*  DESCRIPTION                                                           */
2151 /*                                                                        */
2152 /*    This function handles events of RTSP server thread.                 */
2153 /*                                                                        */
2154 /*  INPUT                                                                 */
2155 /*                                                                        */
2156 /*    rtsp_server_address                   Pointer to RTSP server        */
2157 /*                                                                        */
2158 /*  OUTPUT                                                                */
2159 /*                                                                        */
2160 /*    None                                                                */
2161 /*                                                                        */
2162 /*  CALLS                                                                 */
2163 /*                                                                        */
2164 /*    tx_event_flags_get                    Get event flags               */
2165 /*    _nx_rtsp_server_connect_process       Process connect event         */
2166 /*    _nx_rtsp_server_request_process       Process request event         */
2167 /*    _nx_rtsp_server_disconnect_process    Process disconnect event      */
2168 /*    _nx_rtsp_server_timeout_process       Process timeout event         */
2169 /*                                                                        */
2170 /*  CALLED BY                                                             */
2171 /*                                                                        */
2172 /*    ThreadX                                                             */
2173 /*                                                                        */
2174 /*  RELEASE HISTORY                                                       */
2175 /*                                                                        */
2176 /*    DATE              NAME                      DESCRIPTION             */
2177 /*                                                                        */
2178 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2179 /*                                                                        */
2180 /**************************************************************************/
_nx_rtsp_server_thread_entry(ULONG rtsp_server_address)2181 static VOID _nx_rtsp_server_thread_entry(ULONG rtsp_server_address)
2182 {
2183 NX_RTSP_SERVER *rtsp_server_ptr;
2184 UINT            status;
2185 ULONG           events;
2186 
2187 
2188     /* Setup the server pointer.  */
2189     rtsp_server_ptr = (NX_RTSP_SERVER *)rtsp_server_address;
2190 
2191     /* Loop to process RTSP Server requests.  */
2192     while (1)
2193     {
2194 
2195         /* Wait for an RTSP client activity.  */
2196         status = tx_event_flags_get(&(rtsp_server_ptr -> nx_rtsp_server_event_flags), NX_RTSP_SERVER_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER);
2197 
2198         /* Check the return status.  */
2199         if (status)
2200         {
2201 
2202             /* If an error occurs, simply continue the loop.  */
2203             continue;
2204         }
2205 
2206         /* Otherwise, an event is present.  Process according to the event.  */
2207 
2208         /* Check for a client connection event.  */
2209         if (events & NX_RTSP_SERVER_CONNECT_EVENT)
2210         {
2211 
2212             /* Call the connect process.  */
2213             _nx_rtsp_server_connect_process(rtsp_server_ptr);
2214         }
2215 
2216         /* Check for a client request event.  */
2217         if (events & NX_RTSP_SERVER_REQUEST_EVENT)
2218         {
2219 
2220             /* Call the request process.  */
2221             _nx_rtsp_server_request_process(rtsp_server_ptr);
2222         }
2223 
2224         /* Check for a client disconnect event.  */
2225         if (events & NX_RTSP_SERVER_DISCONNECT_EVENT)
2226         {
2227 
2228             /* Call the disconnect process.  */
2229             _nx_rtsp_server_disconnect_process(rtsp_server_ptr);
2230         }
2231 
2232         /* Check for a client activity timeout event.  */
2233         if (events & NX_RTSP_SERVER_TIMEOUT_EVENT)
2234         {
2235 
2236             /* Call the activity timeout process.  */
2237             _nx_rtsp_server_timeout_process(rtsp_server_ptr);
2238         }
2239     }
2240 }
2241 
2242 /**************************************************************************/
2243 /*                                                                        */
2244 /*  FUNCTION                                               RELEASE        */
2245 /*                                                                        */
2246 /*    _nx_rtsp_server_request_receive                     PORTABLE C      */
2247 /*                                                           6.3.0        */
2248 /*  AUTHOR                                                                */
2249 /*                                                                        */
2250 /*    Wenhui Xie, Microsoft Corporation                                   */
2251 /*                                                                        */
2252 /*  DESCRIPTION                                                           */
2253 /*                                                                        */
2254 /*    This function receives the entire request from client including the */
2255 /*    request header and message body.                                    */
2256 /*                                                                        */
2257 /*  INPUT                                                                 */
2258 /*                                                                        */
2259 /*    rtsp_server_ptr                       Pointer to RTSP server        */
2260 /*    rtsp_client_ptr                       Pointer to RTSP client        */
2261 /*                                                                        */
2262 /*  OUTPUT                                                                */
2263 /*                                                                        */
2264 /*    None                                                                */
2265 /*                                                                        */
2266 /*  CALLS                                                                 */
2267 /*                                                                        */
2268 /*    nx_tcp_socket_receive                 Receive TCP packet            */
2269 /*    _nx_rtsp_server_memicmp               Compare two strings           */
2270 /*    nx_packet_data_append                 Append packet data            */
2271 /*    nx_packet_release                     Release the packet            */
2272 /*                                                                        */
2273 /*  CALLED BY                                                             */
2274 /*                                                                        */
2275 /*    _nx_rtsp_server_request_process                                     */
2276 /*                                                                        */
2277 /*  RELEASE HISTORY                                                       */
2278 /*                                                                        */
2279 /*    DATE              NAME                      DESCRIPTION             */
2280 /*                                                                        */
2281 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2282 /*                                                                        */
2283 /**************************************************************************/
_nx_rtsp_server_request_receive(NX_RTSP_SERVER * rtsp_server_ptr,NX_RTSP_CLIENT * rtsp_client_ptr)2284 static UINT _nx_rtsp_server_request_receive(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr)
2285 {
2286 NX_PACKET *head_packet_ptr = rtsp_client_ptr -> nx_rtsp_client_request_packet;
2287 NX_PACKET *new_packet_ptr;
2288 NX_PACKET *work_ptr;
2289 NX_PACKET *tmp_ptr;
2290 UCHAR     *buffer_ptr;
2291 UINT       crlf_found = 0;
2292 UINT       content_length_found = 0;
2293 UINT       content_length = 0;
2294 UINT       header_length = 0;
2295 UINT       status = NX_SUCCESS;
2296 
2297 
2298     if (head_packet_ptr == NX_NULL)
2299     {
2300 
2301         /* Receive a request from RTSP client.  */
2302         status = nx_tcp_socket_receive(&(rtsp_client_ptr -> nx_rtsp_client_socket), &head_packet_ptr, NX_NO_WAIT);
2303 
2304         /* Check the return status.  */
2305         if (status == NX_NO_PACKET)
2306         {
2307             return(NX_IN_PROGRESS);
2308         }
2309         else if (status != NX_SUCCESS)
2310         {
2311 
2312             /* Return an error condition.  */
2313             return(status);
2314         }
2315 
2316         rtsp_client_ptr -> nx_rtsp_client_request_packet = head_packet_ptr;
2317     }
2318 
2319     work_ptr = head_packet_ptr;
2320 
2321     /* Build a pointer to the buffer area.  */
2322     buffer_ptr = work_ptr -> nx_packet_prepend_ptr;
2323 
2324     while (status == NX_SUCCESS)
2325     {
2326 
2327         /* nx_rtsp_client_request_bytes_total is not zero means the receiving of request header is complete.  */
2328         if (rtsp_client_ptr -> nx_rtsp_client_request_bytes_total == 0)
2329         {
2330 
2331             /* See if there is a blank line present in the buffer.  */
2332             /* Search the buffer for a cr/lf pair.  */
2333             while ((buffer_ptr < work_ptr -> nx_packet_append_ptr) &&
2334                    (crlf_found < 4))
2335             {
2336                 if (!(crlf_found & 1) && (*buffer_ptr == '\r'))
2337                 {
2338 
2339                     /* Found CR.  */
2340                     crlf_found++;
2341                 }
2342                 else if ((crlf_found & 1) && (*buffer_ptr == '\n'))
2343                 {
2344 
2345                     /* Found LF.  */
2346                     crlf_found++;
2347                 }
2348                 else
2349                 {
2350 
2351                     /* Reset the CRLF marker.  */
2352                     crlf_found = 0;
2353                 }
2354 
2355                 if ((content_length_found == NX_FALSE) && ((buffer_ptr + 14) < work_ptr -> nx_packet_append_ptr) &&
2356                     (_nx_rtsp_server_memicmp(buffer_ptr, 15, NX_RTSP_SERVER_STRING_WITH_SIZE("Content-length:")) == NX_SUCCESS))
2357                 {
2358 
2359                     /* Set the found flag.  */
2360                     content_length_found = NX_TRUE;
2361                     buffer_ptr += 15;
2362                     header_length += 15;
2363 
2364                     /* Now skip over white space.  */
2365                     while ((buffer_ptr < work_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
2366                     {
2367                         buffer_ptr++;
2368                         header_length++;
2369                     }
2370 
2371                     /* Now convert the length into a numeric value.  */
2372                     while ((buffer_ptr < work_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
2373                     {
2374 
2375                         /* Update the content length.  */
2376                         content_length =  content_length * 10;
2377                         content_length = content_length + (UINT)(*buffer_ptr) - '0';
2378 
2379                         /* Move the buffer pointer forward.  */
2380                         buffer_ptr++;
2381                         header_length++;
2382                     }
2383                 }
2384 
2385                 /* Move the buffer pointer up.  */
2386                 buffer_ptr++;
2387                 header_length++;
2388             }
2389 
2390             if (crlf_found == 4)
2391             {
2392 
2393                 /* Store content length and total bytes need to be received.  */
2394                 rtsp_client_ptr -> nx_rtsp_client_request_content_length = content_length;
2395                 rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = content_length + header_length;
2396 
2397                 /* Yes, we have found the end of the HTTP request header. Continue to receive content  */
2398                 continue;
2399             }
2400 
2401 #ifndef NX_DISABLE_PACKET_CHAIN
2402 
2403             /* Determine if the packet has already overflowed into another packet.  */
2404             if (work_ptr -> nx_packet_next != NX_NULL)
2405             {
2406 
2407                 /* Get the next packet in the chain.  */
2408                 work_ptr  = work_ptr -> nx_packet_next;
2409                 buffer_ptr = work_ptr -> nx_packet_prepend_ptr;
2410 
2411                 continue;
2412             }
2413 #endif /* NX_DISABLE_PACKET_CHAIN */
2414         }
2415         else
2416         {
2417 
2418             /* Check if we have received the total bytes of the request.  */
2419             if (head_packet_ptr -> nx_packet_length == rtsp_client_ptr -> nx_rtsp_client_request_bytes_total)
2420             {
2421                 break;
2422             }
2423             else if (head_packet_ptr -> nx_packet_length > rtsp_client_ptr -> nx_rtsp_client_request_bytes_total)
2424             {
2425                 status = NX_INVALID_PACKET;
2426                 break;
2427             }
2428         }
2429 
2430         /* Receive another packet from the RTSP Client.  */
2431         status = nx_tcp_socket_receive(&(rtsp_client_ptr -> nx_rtsp_client_socket), &new_packet_ptr, NX_NO_WAIT);
2432 
2433         /* Check the return status.  */
2434         if (status == NX_NO_PACKET)
2435         {
2436             return(NX_IN_PROGRESS);
2437         }
2438         else if (status != NX_SUCCESS)
2439         {
2440             break;
2441         }
2442 
2443         /* Successfully received another packet. Its contents now need to be placed in the head packet.  */
2444         tmp_ptr = new_packet_ptr;
2445 
2446 #ifndef NX_DISABLE_PACKET_CHAIN
2447         while (tmp_ptr)
2448 #endif /* NX_DISABLE_PACKET_CHAIN */
2449         {
2450 
2451             /* Copy the contents of the current packet into the head packet.  */
2452             status = nx_packet_data_append(head_packet_ptr, (VOID *) tmp_ptr -> nx_packet_prepend_ptr,
2453                                             (ULONG)(tmp_ptr -> nx_packet_append_ptr - tmp_ptr -> nx_packet_prepend_ptr),
2454                                             rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_NO_WAIT);
2455 
2456 #ifndef NX_DISABLE_PACKET_CHAIN
2457 
2458             /* Determine if an error occurred.  */
2459             if (status != NX_SUCCESS)
2460             {
2461                 break;
2462             }
2463             else
2464             {
2465                 tmp_ptr = tmp_ptr -> nx_packet_next;
2466             }
2467 #endif /* NX_DISABLE_PACKET_CHAIN */
2468         }
2469 
2470         /* Release the new packet.  */
2471         nx_packet_release(new_packet_ptr);
2472 
2473         /* If we haven't received all the request header, and haven't found the content length field.  */
2474         if ((rtsp_client_ptr -> nx_rtsp_client_request_bytes_total == 0) && (content_length_found == NX_FALSE))
2475         {
2476 
2477             /* Search again from the start of the packet.  */
2478             work_ptr = head_packet_ptr;
2479 
2480             /* Build a pointer to the buffer area.  */
2481             buffer_ptr = work_ptr -> nx_packet_prepend_ptr;
2482 
2483             /* Reset the header length.  */
2484             header_length = 0;
2485         }
2486     }
2487 
2488     if (status)
2489     {
2490 
2491         /* Release the packet.  */
2492         nx_packet_release(head_packet_ptr);
2493         rtsp_client_ptr -> nx_rtsp_client_request_packet = NX_NULL;
2494         rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = 0;
2495     }
2496 
2497     /* Return status.  */
2498     return(status);
2499 }
2500 
2501 /**************************************************************************/
2502 /*                                                                        */
2503 /*  FUNCTION                                               RELEASE        */
2504 /*                                                                        */
2505 /*    _nx_rtsp_server_request_parse                       PORTABLE C      */
2506 /*                                                           6.3.0        */
2507 /*  AUTHOR                                                                */
2508 /*                                                                        */
2509 /*    Wenhui Xie, Microsoft Corporation                                   */
2510 /*                                                                        */
2511 /*  DESCRIPTION                                                           */
2512 /*                                                                        */
2513 /*    This function parses incoming request packet.                       */
2514 /*                                                                        */
2515 /*  INPUT                                                                 */
2516 /*                                                                        */
2517 /*    rtsp_client_ptr                       Pointer to RTSP client        */
2518 /*    rtsp_client_request_ptr               Pointer to request structure  */
2519 /*                                                                        */
2520 /*  OUTPUT                                                                */
2521 /*                                                                        */
2522 /*    status                                Completion status             */
2523 /*                                                                        */
2524 /*  CALLS                                                                 */
2525 /*                                                                        */
2526 /*    memset                                Reset memory                  */
2527 /*    _nx_rtsp_server_request_line_parse    Parse request line            */
2528 /*    _nx_rtsp_server_request_header_parse  Parse request header          */
2529 /*    nx_packet_allocate                    Allocate a packet             */
2530 /*    _nx_rtsp_server_error_response_send   Send error response           */
2531 /*                                                                        */
2532 /*  CALLED BY                                                             */
2533 /*                                                                        */
2534 /*    _nx_rtsp_server_request_process                                     */
2535 /*                                                                        */
2536 /*  RELEASE HISTORY                                                       */
2537 /*                                                                        */
2538 /*    DATE              NAME                      DESCRIPTION             */
2539 /*                                                                        */
2540 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2541 /*                                                                        */
2542 /**************************************************************************/
_nx_rtsp_server_request_parse(NX_RTSP_CLIENT * rtsp_client_ptr,NX_RTSP_CLIENT_REQUEST * rtsp_client_request_ptr)2543 static UINT _nx_rtsp_server_request_parse(NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr)
2544 {
2545 UINT   status;
2546 UCHAR *rtsp_client_request_buf;
2547 UCHAR *rtsp_client_request_buf_ptr;
2548 UCHAR *rtsp_client_request_buf_end;
2549 NX_PACKET *rtsp_client_request_packet = rtsp_client_ptr -> nx_rtsp_client_request_packet;
2550 
2551 
2552 #ifndef NX_DISABLE_PACKET_CHAIN
2553 
2554     /* Check if the packet is chained. Chained packet isn't supported now.  */
2555     if (rtsp_client_request_packet -> nx_packet_next)
2556     {
2557         return(NX_INVALID_PACKET);
2558     }
2559 #endif /* NX_DISABLE_PACKET_CHAIN */
2560 
2561     /* Reset the request info.  */
2562     memset(rtsp_client_request_ptr, 0, sizeof(NX_RTSP_CLIENT_REQUEST));
2563 
2564     /* Set the buffer pointer.  */
2565     rtsp_client_request_buf = rtsp_client_request_packet -> nx_packet_prepend_ptr;
2566     rtsp_client_request_buf_end = rtsp_client_request_packet -> nx_packet_append_ptr - rtsp_client_ptr -> nx_rtsp_client_request_content_length;
2567     rtsp_client_request_buf_ptr = rtsp_client_request_buf;
2568 
2569     /* Parse the request line.  */
2570     status = _nx_rtsp_server_request_line_parse(rtsp_client_request_ptr, &rtsp_client_request_buf_ptr, rtsp_client_request_buf_end);
2571 
2572     if (status == NX_SUCCESS)
2573     {
2574 
2575         /* Continue parse headers.  */
2576         while (rtsp_client_request_buf_ptr < rtsp_client_request_buf_end)
2577         {
2578 
2579             /* Parse the headers.  */
2580             status = _nx_rtsp_server_request_header_parse(rtsp_client_ptr, rtsp_client_request_ptr,
2581                                                           &rtsp_client_request_buf_ptr, rtsp_client_request_buf_end);
2582 
2583             if (status)
2584             {
2585                 break;
2586             }
2587         }
2588     }
2589 
2590     if (status)
2591     {
2592 
2593         /* Send error response packet.  */
2594         if (nx_packet_allocate(rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool,
2595                                &(rtsp_client_ptr -> nx_rtsp_client_response_packet),
2596                                NX_TCP_PACKET, NX_RTSP_SERVER_PACKET_TIMEOUT) == NX_SUCCESS)
2597         {
2598             _nx_rtsp_server_error_response_send(rtsp_client_ptr, status);
2599         }
2600         else
2601         {
2602 
2603             /* There is nothing we can do here. Ideally log this error event.  */
2604             rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_allocation_errors++;
2605         }
2606     }
2607 
2608     return(status);
2609 }
2610 
2611 /**************************************************************************/
2612 /*                                                                        */
2613 /*  FUNCTION                                               RELEASE        */
2614 /*                                                                        */
2615 /*    _nx_rtsp_server_request_line_parse                  PORTABLE C      */
2616 /*                                                           6.3.0        */
2617 /*  AUTHOR                                                                */
2618 /*                                                                        */
2619 /*    Wenhui Xie, Microsoft Corporation                                   */
2620 /*                                                                        */
2621 /*  DESCRIPTION                                                           */
2622 /*                                                                        */
2623 /*    This function parses request method, URI and version.               */
2624 /*                                                                        */
2625 /*  INPUT                                                                 */
2626 /*                                                                        */
2627 /*    rtsp_client_request_ptr               Pointer to request structure  */
2628 /*    request_buffer                        Start of request buffer       */
2629 /*    request_buffer_end                    End to request buffer         */
2630 /*                                                                        */
2631 /*  OUTPUT                                                                */
2632 /*                                                                        */
2633 /*    status                                Completion status             */
2634 /*                                                                        */
2635 /*  CALLS                                                                 */
2636 /*                                                                        */
2637 /*    memcmp                                Compare two strings           */
2638 /*                                                                        */
2639 /*  CALLED BY                                                             */
2640 /*                                                                        */
2641 /*    _nx_rtsp_server_request_parse                                       */
2642 /*                                                                        */
2643 /*  RELEASE HISTORY                                                       */
2644 /*                                                                        */
2645 /*    DATE              NAME                      DESCRIPTION             */
2646 /*                                                                        */
2647 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2648 /*                                                                        */
2649 /**************************************************************************/
_nx_rtsp_server_request_line_parse(NX_RTSP_CLIENT_REQUEST * rtsp_client_request_ptr,UCHAR ** request_buffer,UCHAR * request_buffer_end)2650 static UINT _nx_rtsp_server_request_line_parse(NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr, UCHAR **request_buffer, UCHAR *request_buffer_end)
2651 {
2652 UCHAR *request_buffer_ptr;
2653 UCHAR *temp_ptr;
2654 UINT   temp_length = 0;
2655 
2656 
2657     /* Set the buffer pointer.  */
2658     request_buffer_ptr = *request_buffer;
2659 
2660     /* We assume the client request is well formatted. */
2661     /* Parse the request line.  */
2662 
2663     /* Trim the spaces before the method.  */
2664     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr == ' '))
2665     {
2666         request_buffer_ptr++;
2667     }
2668 
2669     /* Return error if no more data.  */
2670     if (request_buffer_ptr == request_buffer_end)
2671     {
2672         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2673     }
2674 
2675     /* Set the method pointer.  */
2676     temp_ptr = request_buffer_ptr;
2677 
2678     /* Find the ending point of the method.  */
2679     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr != ' ') &&
2680            (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
2681     {
2682         request_buffer_ptr++;
2683     }
2684 
2685     /* Must has space before URI.  */
2686     if ((request_buffer_ptr == request_buffer_end) || (*request_buffer_ptr != ' '))
2687     {
2688         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2689     }
2690 
2691     /* Calculate method length.  */
2692     temp_length = (UINT)(request_buffer_ptr - temp_ptr);
2693 
2694     /* The method is case-sensitive.  */
2695     if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("OPTIONS")) && (memcmp(temp_ptr, "OPTIONS", temp_length) == 0))
2696     {
2697         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_OPTIONS;
2698     }
2699     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("DESCRIBE")) && (memcmp(temp_ptr, "DESCRIBE", temp_length) == 0))
2700     {
2701         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_DESCRIBE;
2702     }
2703     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("SETUP")) && (memcmp(temp_ptr, "SETUP", temp_length) == 0))
2704     {
2705         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_SETUP;
2706     }
2707     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("PLAY")) && (memcmp(temp_ptr, "PLAY", temp_length) == 0))
2708     {
2709         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_PLAY;
2710     }
2711     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("PAUSE")) && (memcmp(temp_ptr, "PAUSE", temp_length) == 0))
2712     {
2713         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_PAUSE;
2714     }
2715     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("TEARDOWN")) && (memcmp(temp_ptr, "TEARDOWN", temp_length) == 0))
2716     {
2717         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_TEARDOWN;
2718     }
2719     else if ((temp_length == NX_RTSP_SERVER_STRING_SIZE("SET_PARAMETER")) && (memcmp(temp_ptr, "SET_PARAMETER", temp_length) == 0))
2720     {
2721         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_SET_PARAMETER;
2722     }
2723     else
2724     {
2725         rtsp_client_request_ptr -> nx_rtsp_client_request_method = NX_RTSP_METHOD_NOT_SUPPORT;
2726 
2727         return(NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED);
2728     }
2729 
2730     /* Trim the spaces.  */
2731     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr == ' '))
2732     {
2733         request_buffer_ptr++;
2734     }
2735 
2736     /* Return error if no more data.  */
2737     if (request_buffer_ptr == request_buffer_end)
2738     {
2739         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2740     }
2741 
2742     /* Set the URI pointer.  */
2743     rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr = request_buffer_ptr;
2744 
2745     /* Find the ending point of the URI.  */
2746     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr != ' ') &&
2747            (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
2748     {
2749         request_buffer_ptr++;
2750     }
2751 
2752     /* Must has space before version.  */
2753     if ((request_buffer_ptr == request_buffer_end) || (*request_buffer_ptr != ' '))
2754     {
2755         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2756     }
2757 
2758     /* Calculate the URI length.  */
2759     rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length = (UINT)(request_buffer_ptr - rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr);
2760 
2761     /* Trim the spaces.  */
2762     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr == ' '))
2763     {
2764         request_buffer_ptr++;
2765     }
2766 
2767     /* Return error if no more data.  */
2768     if (request_buffer_ptr == request_buffer_end)
2769     {
2770         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2771     }
2772 
2773     /* Set the version pointer.  */
2774     temp_ptr = request_buffer_ptr;
2775 
2776     /* Find the ending point of the version.  */
2777     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr != ' ') &&
2778            (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
2779     {
2780         request_buffer_ptr++;
2781     }
2782 
2783     /* Calculate version length.  */
2784     temp_length = (UINT)(request_buffer_ptr - temp_ptr);
2785 
2786     /* Check version.  */
2787     if ((temp_length != (sizeof(NX_RTSP_VERSION_STRING) - 1)) ||
2788         memcmp(temp_ptr, NX_RTSP_VERSION_STRING, temp_length) != 0)
2789     {
2790         return(NX_RTSP_STATUS_CODE_RTSP_VERSION_NOT_SUPPORTED);
2791     }
2792 
2793     /* Trim the spaces.  */
2794     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr == ' '))
2795     {
2796         request_buffer_ptr++;
2797     }
2798 
2799     /* Move to next line.  */
2800     /* RFC: https://www.rfc-editor.org/rfc/rfc2326#section-4
2801        Lines are terminated by CRLF, but receivers should be prepared
2802        to also interpret CR and LF by themselves as line terminators. */
2803     if (((request_buffer_ptr + 1) < request_buffer_end) &&
2804         (*request_buffer_ptr == '\r') && (*(request_buffer_ptr + 1) == '\n'))
2805     {
2806         request_buffer_ptr += 2;
2807     }
2808     else if ((request_buffer_ptr < request_buffer_end) &&
2809              ((*request_buffer_ptr == '\r') || (*request_buffer_ptr == '\n')))
2810     {
2811         request_buffer_ptr++;
2812     }
2813     else
2814     {
2815         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2816     }
2817 
2818     *request_buffer = request_buffer_ptr;
2819 
2820     /* Terminate the URI string.  */
2821     *(rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr + rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length) = NX_NULL;
2822 
2823     return(NX_SUCCESS);
2824 }
2825 
2826 /**************************************************************************/
2827 /*                                                                        */
2828 /*  FUNCTION                                               RELEASE        */
2829 /*                                                                        */
2830 /*    _nx_rtsp_server_request_header_parse                PORTABLE C      */
2831 /*                                                           6.3.0        */
2832 /*  AUTHOR                                                                */
2833 /*                                                                        */
2834 /*    Wenhui Xie, Microsoft Corporation                                   */
2835 /*                                                                        */
2836 /*  DESCRIPTION                                                           */
2837 /*                                                                        */
2838 /*    This function parses headers in request packet.                     */
2839 /*                                                                        */
2840 /*  INPUT                                                                 */
2841 /*                                                                        */
2842 /*    rtsp_client_ptr                       Pointer to RTSP client        */
2843 /*    rtsp_client_request_ptr               Pointer to request structure  */
2844 /*    request_buffer                        Start of request buffer       */
2845 /*    request_buffer_end                    End to request buffer         */
2846 /*                                                                        */
2847 /*  OUTPUT                                                                */
2848 /*                                                                        */
2849 /*    status                                Completion status             */
2850 /*                                                                        */
2851 /*  CALLS                                                                 */
2852 /*                                                                        */
2853 /*    _nx_rtsp_server_memicmp               Compare two strings           */
2854 /*    _nx_utility_string_to_uint            Convert string to integer     */
2855 /*    _nx_rtsp_server_strstr                Search substring              */
2856 /*                                                                        */
2857 /*  CALLED BY                                                             */
2858 /*                                                                        */
2859 /*    _nx_rtsp_server_request_parse                                       */
2860 /*                                                                        */
2861 /*  RELEASE HISTORY                                                       */
2862 /*                                                                        */
2863 /*    DATE              NAME                      DESCRIPTION             */
2864 /*                                                                        */
2865 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
2866 /*                                                                        */
2867 /**************************************************************************/
_nx_rtsp_server_request_header_parse(NX_RTSP_CLIENT * rtsp_client_ptr,NX_RTSP_CLIENT_REQUEST * rtsp_client_request_ptr,UCHAR ** request_buffer,UCHAR * request_buffer_end)2868 static UINT _nx_rtsp_server_request_header_parse(NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr, UCHAR **request_buffer, UCHAR *request_buffer_end)
2869 {
2870 UCHAR *request_buffer_ptr;
2871 UCHAR *field_name_ptr;
2872 UCHAR *field_value_ptr;
2873 UINT   field_name_length = 0;
2874 UINT   field_value_length = 0;
2875 UINT   port_length = 0;
2876 UINT   status;
2877 NXD_ADDRESS *receiver_ip_address;
2878 
2879 
2880     /* Set the buffer pointer.  */
2881     request_buffer_ptr = *request_buffer;
2882 
2883     /* We assume the client request is well formatted.  */
2884     /* Parse a header line.  */
2885 
2886     /* Trim the spaces.  */
2887     while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr == ' '))
2888     {
2889         request_buffer_ptr++;
2890     }
2891 
2892     if (request_buffer_ptr == request_buffer_end)
2893     {
2894 
2895         /* Ignore empty line */
2896         return(NX_SUCCESS);
2897     }
2898 
2899     /* Set the pointer of field name.  */
2900     field_name_ptr = request_buffer_ptr;
2901 
2902     /* Find the ending point of the header name.  */
2903     while ((request_buffer_ptr < request_buffer_end) &&
2904            (*request_buffer_ptr != ':') && (*request_buffer_ptr != ' ') &&
2905            (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
2906     {
2907         request_buffer_ptr++;
2908     }
2909 
2910     /* Calculate the length of the field name.  */
2911     field_name_length = (UINT)(request_buffer_ptr - field_name_ptr);
2912 
2913     if (field_name_length)
2914     {
2915 
2916         /* Trim the colon and spaces.  */
2917         while ((request_buffer_ptr < request_buffer_end) &&
2918                ((*request_buffer_ptr == ':') || (*request_buffer_ptr == ' ')))
2919         {
2920             request_buffer_ptr++;
2921         }
2922 
2923         /* Set the pointer of the field value.  */
2924         field_value_ptr = request_buffer_ptr;
2925 
2926         /* Find the end of the field value.  */
2927         while ((request_buffer_ptr < request_buffer_end) &&
2928                 (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
2929         {
2930             request_buffer_ptr++;
2931         }
2932 
2933         /* Calculate the length of the field value.  */
2934         field_value_length = (UINT)(request_buffer_ptr - field_value_ptr);
2935 
2936         if (_nx_rtsp_server_memicmp(field_name_ptr, field_name_length, NX_RTSP_SERVER_STRING_WITH_SIZE("cseq")) == NX_SUCCESS)
2937         {
2938 
2939             /* Parse CSeq.  */
2940 
2941             /* Convert string to integer.  */
2942             status = _nx_utility_string_to_uint((CHAR *)field_value_ptr, field_value_length, &(rtsp_client_request_ptr -> nx_rtsp_client_request_sequence_number));
2943             if (status)
2944             {
2945                 return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
2946             }
2947         }
2948         else if (_nx_rtsp_server_memicmp(field_name_ptr, field_name_length, NX_RTSP_SERVER_STRING_WITH_SIZE("range")) == NX_SUCCESS)
2949         {
2950 
2951             /* Parse Range.  */
2952 
2953             /* Set the range pointer and length.  */
2954             rtsp_client_request_ptr -> nx_rtsp_client_request_range_ptr = field_value_ptr;
2955             rtsp_client_request_ptr -> nx_rtsp_client_request_range_length = field_value_length;
2956         }
2957         else if (_nx_rtsp_server_memicmp(field_name_ptr, field_name_length, NX_RTSP_SERVER_STRING_WITH_SIZE("session")) == NX_SUCCESS)
2958         {
2959 
2960             /* Parse Session.  */
2961 
2962             /* Convert string to integer.  */
2963             status = _nx_utility_string_to_uint((CHAR *)field_value_ptr, field_value_length, (UINT *)&(rtsp_client_request_ptr -> nx_rtsp_client_request_session_id));
2964             if (status)
2965             {
2966                 return(status);
2967             }
2968         }
2969         else if (_nx_rtsp_server_memicmp(field_name_ptr, field_name_length, NX_RTSP_SERVER_STRING_WITH_SIZE("transport")) == NX_SUCCESS)
2970         {
2971 
2972             /* Parse Transport.  */
2973 
2974             /* RTP/AVP/TCP is not supported. https://www.rfc-editor.org/rfc/rfc2326#section-10.4.  */
2975             if (_nx_rtsp_server_strstr(field_value_ptr, field_value_length, NX_RTSP_SERVER_STRING_WITH_SIZE("RTP/AVP/TCP")))
2976             {
2977                 rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_type = NX_RTSP_TRANSPORT_TYPE_TCP;
2978                 return(NX_RTSP_STATUS_CODE_UNSUPPORTED_TRANSPORT);
2979             }
2980             else
2981             {
2982                 rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_type = NX_RTSP_TRANSPORT_TYPE_UDP;
2983             }
2984 
2985             receiver_ip_address = &(rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_connect_ip);
2986 
2987             /* Check multicast/unicast field.  */
2988             if (_nx_rtsp_server_strstr(field_value_ptr, field_value_length, NX_RTSP_SERVER_STRING_WITH_SIZE("unicast")))
2989             {
2990 
2991                 /* For unicast mode, set the client IP address and return to user.  */
2992                 rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode = NX_RTSP_TRANSPORT_MODE_UNICAST;
2993 
2994                 if (receiver_ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
2995                 {
2996 #ifndef NX_DISABLE_IPV4
2997                     /* Set client IP address. */
2998                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
2999                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_ip_address.nxd_ip_address.v4 = receiver_ip_address -> nxd_ip_address.v4;
3000 
3001                     /* Set default server IP address.  */
3002                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
3003                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_ip_address.nxd_ip_address.v4 = rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address;
3004 
3005                     /* Record the transport ip interface in order to know where the packet is from.  */
3006                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.interface_index = rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_index;
3007 #else
3008                     return(NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED);
3009 #endif /* NX_DISABLE_IPV4 */
3010                 }
3011                 else if (receiver_ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
3012                 {
3013 #ifdef FEATURE_NX_IPV6
3014                     /* Set client IP address. */
3015                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_ip_address.nxd_ip_version = NX_IP_VERSION_V6;
3016                     COPY_IPV6_ADDRESS(receiver_ip_address -> nxd_ip_address.v6, rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_ip_address.nxd_ip_address.v6);
3017 
3018                     /* Set default server IP address.  */
3019                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_ip_address.nxd_ip_version = NX_IP_VERSION_V6;
3020                     COPY_IPV6_ADDRESS(rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_ipv6_addr -> nxd_ipv6_address,
3021                                       rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_ip_address.nxd_ip_address.v6);
3022 
3023                     /* Record the transport ip interface in order to know where the packet is from.  */
3024                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.interface_index = rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached -> nx_interface_index;
3025 #else
3026                     return(NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED);
3027 #endif /* FEATURE_NX_IPV6 */
3028                 }
3029                 else
3030                 {
3031                     return(NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED);
3032                 }
3033 
3034                 request_buffer_ptr = _nx_rtsp_server_strstr(field_value_ptr, field_value_length, NX_RTSP_SERVER_STRING_WITH_SIZE("client_port"));
3035                 port_length = NX_RTSP_SERVER_STRING_SIZE("client_port");
3036             }
3037             else
3038             {
3039 
3040                 /* FIXME: Support that client chooses multicast address. Get destination field and convert to IP address.  */
3041                 if (_nx_rtsp_server_strstr(field_value_ptr, field_value_length, NX_RTSP_SERVER_STRING_WITH_SIZE("destination")) != NX_NULL)
3042                 {
3043                     rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode = NX_RTSP_TRANSPORT_MODE_MULTICAST_CLIENT;
3044                     return(NX_RTSP_STATUS_CODE_UNSUPPORTED_TRANSPORT);
3045                 }
3046 
3047                 /* Set multicast mode and server will choose multicast address.  */
3048                 rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode = NX_RTSP_TRANSPORT_MODE_MULTICAST_SERVER;
3049                 request_buffer_ptr = _nx_rtsp_server_strstr(field_value_ptr, field_value_length, NX_RTSP_SERVER_STRING_WITH_SIZE("port"));
3050                 port_length = NX_RTSP_SERVER_STRING_SIZE("port");
3051             }
3052 
3053             /* Get client port pair.  */
3054             if (request_buffer_ptr)
3055             {
3056 
3057                 /* Find the port value.  */
3058                 request_buffer_ptr = request_buffer_ptr + port_length;
3059                 while ((request_buffer_ptr < request_buffer_end) &&
3060                        ((*request_buffer_ptr == ' ') || (*request_buffer_ptr == '=')))
3061                 {
3062                     request_buffer_ptr++;
3063                 }
3064 
3065                 /* Get pointer of the RTP port.  */
3066                 field_value_ptr = request_buffer_ptr;
3067 
3068                 while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr != '-') &&
3069                        (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
3070                 {
3071                     request_buffer_ptr++;
3072                 }
3073 
3074                 /* Check the format.  */
3075                 if (*request_buffer_ptr != '-')
3076                 {
3077                     return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
3078                 }
3079 
3080                 /* Calculate the length of the RTP port.  */
3081                 field_value_length = (UINT)(request_buffer_ptr - field_value_ptr);
3082 
3083                 /* Convert string to integer.  */
3084                 status = _nx_utility_string_to_uint((CHAR *)field_value_ptr, field_value_length, (UINT *)&(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtp_port));
3085                 if (status)
3086                 {
3087                     return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
3088                 }
3089 
3090                 /* Get pointer of the RTCP port.  */
3091                 request_buffer_ptr++;
3092                 field_value_ptr = request_buffer_ptr;
3093 
3094                 while ((request_buffer_ptr < request_buffer_end) && (*request_buffer_ptr != ';') &&
3095                        (*request_buffer_ptr != '\r') && (*request_buffer_ptr != '\n'))
3096                 {
3097                     request_buffer_ptr++;
3098                 }
3099 
3100                 /* Calculate the length of the RTCP port.  */
3101                 field_value_length = (UINT)(request_buffer_ptr - field_value_ptr);
3102 
3103                 /* Convert string to integer.  */
3104                 status = _nx_utility_string_to_uint((CHAR *)field_value_ptr, field_value_length, (UINT *)&(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtcp_port));
3105                 if (status)
3106                 {
3107                     return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
3108                 }
3109             }
3110             else
3111             {
3112 
3113                 /* If no client port, move to the end of transport field.  */
3114                 request_buffer_ptr = field_value_ptr + field_value_length;
3115             }
3116         }
3117     }
3118 
3119     /* Move to next line.  */
3120     /* RFC: https://www.rfc-editor.org/rfc/rfc2326#section-4
3121        Lines are terminated by CRLF, but receivers should be prepared
3122        to also interpret CR and LF by themselves as line terminators. */
3123     if (((request_buffer_ptr + 1) < request_buffer_end) &&
3124         (*request_buffer_ptr == '\r') && (*(request_buffer_ptr + 1) == '\n'))
3125     {
3126 
3127         /* Terminate the header line.  */
3128         *request_buffer_ptr = NX_NULL;
3129         request_buffer_ptr += 2;
3130     }
3131     else if ((request_buffer_ptr < request_buffer_end) &&
3132              ((*request_buffer_ptr == '\r') || (*request_buffer_ptr == '\n')))
3133     {
3134 
3135         /* Terminate the header line.  */
3136         *request_buffer_ptr = NX_NULL;
3137         request_buffer_ptr++;
3138     }
3139     else
3140     {
3141         return(NX_RTSP_STATUS_CODE_BAD_REQUEST);
3142     }
3143 
3144     *request_buffer = request_buffer_ptr;
3145 
3146     return(NX_SUCCESS);
3147 }
3148 
3149 /**************************************************************************/
3150 /*                                                                        */
3151 /*  FUNCTION                                               RELEASE        */
3152 /*                                                                        */
3153 /*    _nx_rtsp_server_memicmp                             PORTABLE C      */
3154 /*                                                           6.3.0        */
3155 /*  AUTHOR                                                                */
3156 /*                                                                        */
3157 /*    Wenhui Xie, Microsoft Corporation                                   */
3158 /*                                                                        */
3159 /*  DESCRIPTION                                                           */
3160 /*                                                                        */
3161 /*    This function compares two pieces of memory case insensitive.       */
3162 /*                                                                        */
3163 /*  INPUT                                                                 */
3164 /*                                                                        */
3165 /*    src                                   Pointer to source             */
3166 /*    src_length                            Length of source              */
3167 /*    dest                                  Pointer to destination        */
3168 /*    dest_length                           Length of destination         */
3169 /*                                                                        */
3170 /*  OUTPUT                                                                */
3171 /*                                                                        */
3172 /*    status                                Completion status             */
3173 /*                                                                        */
3174 /*  CALLS                                                                 */
3175 /*                                                                        */
3176 /*    None                                                                */
3177 /*                                                                        */
3178 /*  CALLED BY                                                             */
3179 /*                                                                        */
3180 /*    _nx_rtsp_server_request_header_parse                                */
3181 /*    _nx_rtsp_server_request_receive                                     */
3182 /*    _nx_rtsp_server_strstr                                              */
3183 /*                                                                        */
3184 /*  RELEASE HISTORY                                                       */
3185 /*                                                                        */
3186 /*    DATE              NAME                      DESCRIPTION             */
3187 /*                                                                        */
3188 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
3189 /*                                                                        */
3190 /**************************************************************************/
_nx_rtsp_server_memicmp(UCHAR * src,ULONG src_length,UCHAR * dest,ULONG dest_length)3191 static UINT _nx_rtsp_server_memicmp(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length)
3192 {
3193 UCHAR ch;
3194 
3195 
3196     /* Compare the length. */
3197     if(src_length != dest_length)
3198         return(NX_RTSP_SERVER_FAILED);
3199 
3200     while(src_length)
3201     {
3202 
3203         /* Is src lowercase? */
3204         if((*src >= 'a') && (*src <= 'z'))
3205             ch = (UCHAR)(*src - 'a' + 'A');
3206 
3207         /* Is src uppercase? */
3208         else if((*src >= 'A') && (*src <= 'Z'))
3209             ch = (UCHAR)(*src - 'A' + 'a');
3210         else
3211             ch = *src;
3212 
3213         /* Compare case insensitive. */
3214         if((*src != *dest) && (ch != *dest))
3215             return(NX_RTSP_SERVER_FAILED);
3216 
3217         /* Pickup next character. */
3218         src_length--;
3219         src++;
3220         dest++;
3221     }
3222 
3223     return(NX_SUCCESS);
3224 }
3225 
3226 /**************************************************************************/
3227 /*                                                                        */
3228 /*  FUNCTION                                               RELEASE        */
3229 /*                                                                        */
3230 /*    _nx_rtsp_server_strstr                              PORTABLE C      */
3231 /*                                                           6.3.0        */
3232 /*  AUTHOR                                                                */
3233 /*                                                                        */
3234 /*    Wenhui Xie, Microsoft Corporation                                   */
3235 /*                                                                        */
3236 /*  DESCRIPTION                                                           */
3237 /*                                                                        */
3238 /*    This function searches the substring and returns the pointer.       */
3239 /*                                                                        */
3240 /*  INPUT                                                                 */
3241 /*                                                                        */
3242 /*    src                                   Pointer to source             */
3243 /*    src_length                            Length of source              */
3244 /*    dest                                  Pointer to destination        */
3245 /*    dest_length                           Length of destination         */
3246 /*                                                                        */
3247 /*  OUTPUT                                                                */
3248 /*                                                                        */
3249 /*    pointer                               Pointer to the substring      */
3250 /*                                                                        */
3251 /*  CALLS                                                                 */
3252 /*                                                                        */
3253 /*    _nx_rtsp_server_memicmp               Compare two strings           */
3254 /*                                                                        */
3255 /*  CALLED BY                                                             */
3256 /*                                                                        */
3257 /*    _nx_rtsp_server_request_header_parse                                */
3258 /*                                                                        */
3259 /*  RELEASE HISTORY                                                       */
3260 /*                                                                        */
3261 /*    DATE              NAME                      DESCRIPTION             */
3262 /*                                                                        */
3263 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
3264 /*                                                                        */
3265 /**************************************************************************/
_nx_rtsp_server_strstr(UCHAR * src,ULONG src_length,UCHAR * dest,ULONG dest_length)3266 static UCHAR *_nx_rtsp_server_strstr(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length)
3267 {
3268 UINT index = 0;
3269 
3270 
3271     /* Check the src and dest length.  */
3272     if (src_length < dest_length)
3273     {
3274         return(NX_NULL);
3275     }
3276 
3277     /* Loop to search the dest string.  */
3278     while ((index + dest_length <= src_length) &&
3279            (_nx_rtsp_server_memicmp(src + index, dest_length, dest, dest_length) != NX_SUCCESS))
3280     {
3281         index++;
3282     }
3283 
3284     /* Return the pointer.  */
3285     if ((index + dest_length) <= src_length)
3286     {
3287         return(src + index);
3288     }
3289     else
3290     {
3291         return(NX_NULL);
3292     }
3293 }
3294 
3295 /**************************************************************************/
3296 /*                                                                        */
3297 /*  FUNCTION                                               RELEASE        */
3298 /*                                                                        */
3299 /*    _nx_rtsp_server_response_create                     PORTABLE C      */
3300 /*                                                           6.3.0        */
3301 /*  AUTHOR                                                                */
3302 /*                                                                        */
3303 /*    Wenhui Xie, Microsoft Corporation                                   */
3304 /*                                                                        */
3305 /*  DESCRIPTION                                                           */
3306 /*                                                                        */
3307 /*    This function creates a response packet with common lines.          */
3308 /*                                                                        */
3309 /*  INPUT                                                                 */
3310 /*                                                                        */
3311 /*    rtsp_server_ptr                       Pointer to RTSP server        */
3312 /*    rtsp_client_ptr                       Pointer to RTSP client        */
3313 /*    rtsp_client_request_ptr               Pointer to request structure  */
3314 /*                                                                        */
3315 /*  OUTPUT                                                                */
3316 /*                                                                        */
3317 /*    status                                Completion status             */
3318 /*                                                                        */
3319 /*  CALLS                                                                 */
3320 /*                                                                        */
3321 /*    nx_packet_allocate                    Allocate a packet             */
3322 /*    nx_packet_data_append                 Append packet data            */
3323 /*    nx_packet_release                     Release the packet            */
3324 /*    _nx_utility_uint_to_string            Convert integer to string     */
3325 /*                                                                        */
3326 /*  CALLED BY                                                             */
3327 /*                                                                        */
3328 /*    _nx_rtsp_server_request_process                                     */
3329 /*                                                                        */
3330 /*  RELEASE HISTORY                                                       */
3331 /*                                                                        */
3332 /*    DATE              NAME                      DESCRIPTION             */
3333 /*                                                                        */
3334 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
3335 /*                                                                        */
3336 /**************************************************************************/
_nx_rtsp_server_response_create(NX_RTSP_SERVER * rtsp_server_ptr,NX_RTSP_CLIENT * rtsp_client_ptr,NX_RTSP_CLIENT_REQUEST * rtsp_client_request_ptr)3337 static UINT _nx_rtsp_server_response_create(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr)
3338 {
3339 UINT  status;
3340 CHAR  temp_buffer[11];
3341 UINT  temp_length;
3342 
3343 
3344     /* Allocate response packet.  */
3345     status = nx_packet_allocate(rtsp_server_ptr -> nx_rtsp_server_packet_pool, &(rtsp_client_ptr -> nx_rtsp_client_response_packet), NX_TCP_PACKET, NX_RTSP_SERVER_PACKET_TIMEOUT);
3346     if (status)
3347     {
3348         return(status);
3349     }
3350 
3351     /* Generate the common response lines.  */
3352 
3353     /* Set default status as 200 OK.  */
3354     status = nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE(NX_RTSP_VERSION_STRING),
3355                                    rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3356     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE(" 200 OK\r\n"),
3357                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3358 
3359     /* Add "CSeq" header.  */
3360     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("CSeq: "),
3361                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3362     temp_length = _nx_utility_uint_to_string(rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_sequence_number, 10, temp_buffer, sizeof(temp_buffer));
3363     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, temp_buffer, temp_length,
3364                                     rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3365     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
3366                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3367 
3368     /* Add "Server" header.  */
3369     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("Server: "),
3370                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3371     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, rtsp_server_ptr -> nx_rtsp_server_name, rtsp_server_ptr -> nx_rtsp_server_name_length,
3372                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3373     status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
3374                                     rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3375 
3376     /* If the request method is PLAY, add RTP-Info header.  */
3377     if (rtsp_client_request_ptr -> nx_rtsp_client_request_method == NX_RTSP_METHOD_PLAY)
3378     {
3379 
3380         /* Add "RTP-Info" header.  */
3381         status += nx_packet_data_append(rtsp_client_ptr -> nx_rtsp_client_response_packet, NX_RTSP_SERVER_STRING_WITH_SIZE("RTP-Info: "),
3382                                         rtsp_server_ptr -> nx_rtsp_server_packet_pool, NX_RTSP_SERVER_PACKET_TIMEOUT);
3383     }
3384 
3385     /* Check if error occurs.  */
3386     if (status)
3387     {
3388         nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_response_packet);
3389         rtsp_client_ptr -> nx_rtsp_client_response_packet = NX_NULL;
3390     }
3391 
3392     return(status);
3393 }
3394 
3395 #ifdef FEATURE_NX_IPV6
3396 /**************************************************************************/
3397 /*                                                                        */
3398 /*  FUNCTION                                               RELEASE        */
3399 /*                                                                        */
3400 /*    _nx_rtsp_server_ipv6_address_to_string              PORTABLE C      */
3401 /*                                                           6.3.0        */
3402 /*  AUTHOR                                                                */
3403 /*                                                                        */
3404 /*    Haiqing Zhao, Microsoft Corporation                                 */
3405 /*                                                                        */
3406 /*  DESCRIPTION                                                           */
3407 /*                                                                        */
3408 /*    This function converts an ipv6 address from ULONG array format into */
3409 /*    standard ipv6 address string format.                                */
3410 /*                                                                        */
3411 /*  INPUT                                                                 */
3412 /*                                                                        */
3413 /*    ipv6_addr                            Pointer to ULONG array address */
3414 /*    buffer                               Pointer to output string buffer*/
3415 /*    buffer_length                        Max length of output buffer    */
3416 /*    size                                 Real size of output buffer     */
3417 /*                                                                        */
3418 /*  OUTPUT                                                                */
3419 /*                                                                        */
3420 /*    status                               Completion status              */
3421 /*                                                                        */
3422 /*  CALLS                                                                 */
3423 /*                                                                        */
3424 /*    memset                               Reset memory                   */
3425 /*    memcpy                               Copy data memory               */
3426 /*                                                                        */
3427 /*  CALLED BY                                                             */
3428 /*                                                                        */
3429 /*    _nx_rtsp_server_response_send                                       */
3430 /*                                                                        */
3431 /*  RELEASE HISTORY                                                       */
3432 /*                                                                        */
3433 /*    DATE              NAME                      DESCRIPTION             */
3434 /*                                                                        */
3435 /*  10-31-2023     Haiqing Zhao             Initial Version 6.3.0         */
3436 /*                                                                        */
3437 /**************************************************************************/
_nx_rtsp_server_ipv6_address_to_string(ULONG * ipv6_addr,CHAR * buffer,UINT buffer_length,UINT * size)3438 static UINT _nx_rtsp_server_ipv6_address_to_string(ULONG *ipv6_addr, CHAR *buffer, UINT buffer_length, UINT *size)
3439 {
3440 UINT    i, j;
3441 UCHAR   c;
3442 ULONG   val;
3443 CHAR   *cur_pos = buffer;
3444 
3445 
3446     /* Check if the buffer is large enough to contain the ipv6 address in string format. An example ipv6 address string
3447        like "2001:0001:0002:0003:0004:0005:0006:1234" shows that 39 bytes data space is needed for the return buffer.
3448        Overall, the return buffer shall be 40 bytes to include the end '\0' for the output string. */
3449     if (buffer_length < 40)
3450     {
3451         return(NX_SIZE_ERROR);
3452     }
3453 
3454     /* Go through each 4 ULONG values in ipv6 address. */
3455     for (i = 0; i < 4; i++)
3456     {
3457 
3458         /* Get the current ULONG value. */
3459         val = ipv6_addr[i];
3460 
3461         /* Go through each bit of the ULONG to convert. */
3462         for (j = 0; j <= 7; j++)
3463         {
3464 
3465             /* Save the bit off the most significant end. */
3466             c = (UCHAR)((val & 0xF0000000) >> 28);
3467 
3468             /* Make it the most significant byte. */
3469             val = val << 4;
3470 
3471             /* Convert the digit to an ascii character. */
3472             if (c < 10)
3473             {
3474                 *cur_pos = (CHAR)('0' + c);
3475             }
3476             else /* Handle HEX digits... */
3477             {
3478                 *cur_pos = (CHAR)('A' + (c - 10));
3479             }
3480 
3481             /* Move past the digit. */
3482             cur_pos++;
3483 
3484             /* Determine if we need to add a colon. */
3485             if ((j == 3) || (j == 7))
3486             {
3487 
3488                 /* Yes, append the colon and move the pointer past it. */
3489                 *cur_pos = ':';
3490                 cur_pos++;
3491             }
3492         }
3493     }
3494 
3495     /* Assign the last byte to make a complete string.  */
3496     buffer[39] = '\0';
3497 
3498     /* Assign a constant string size 39 as the returned real output buffer size. So far, the returned real size
3499        will always be 39 even if an example ipv6 address string is like "2004:0000:0000:0000:0000:0000:0000:0001"
3500        since ipv6 abbreviation expression is not supported.  */
3501     *size = 39;
3502 
3503     return(NX_SUCCESS);
3504 }
3505 #endif /* FEATURE_NX_IPV6 */
3506 
3507 /**************************************************************************/
3508 /*                                                                        */
3509 /*  FUNCTION                                               RELEASE        */
3510 /*                                                                        */
3511 /*    _nx_rtsp_server_response_send                       PORTABLE C      */
3512 /*                                                           6.3.0        */
3513 /*  AUTHOR                                                                */
3514 /*                                                                        */
3515 /*    Wenhui Xie, Microsoft Corporation                                   */
3516 /*                                                                        */
3517 /*  DESCRIPTION                                                           */
3518 /*                                                                        */
3519 /*    This function sends the response to the client.                     */
3520 /*                                                                        */
3521 /*  INPUT                                                                 */
3522 /*                                                                        */
3523 /*    rtsp_server_ptr                       Pointer to RTSP server        */
3524 /*    rtsp_client_ptr                       Pointer to RTSP client        */
3525 /*    rtsp_client_request_ptr               Pointer to request structure  */
3526 /*                                                                        */
3527 /*  OUTPUT                                                                */
3528 /*                                                                        */
3529 /*    status                                Completion status             */
3530 /*                                                                        */
3531 /*  CALLS                                                                 */
3532 /*                                                                        */
3533 /*    nx_packet_data_append                 Append packet data            */
3534 /*    _nx_utility_uint_to_string            Convert integer to string     */
3535 /*    nx_packet_release                     Release the packet            */
3536 /*    nx_tcp_socket_send                    Send TCP packet               */
3537 /*                                                                        */
3538 /*  CALLED BY                                                             */
3539 /*                                                                        */
3540 /*    _nx_rtsp_server_request_process                                     */
3541 /*                                                                        */
3542 /*  RELEASE HISTORY                                                       */
3543 /*                                                                        */
3544 /*    DATE              NAME                      DESCRIPTION             */
3545 /*                                                                        */
3546 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
3547 /*                                                                        */
3548 /**************************************************************************/
_nx_rtsp_server_response_send(NX_RTSP_SERVER * rtsp_server_ptr,NX_RTSP_CLIENT * rtsp_client_ptr,NX_RTSP_CLIENT_REQUEST * rtsp_client_request_ptr)3549 static UINT _nx_rtsp_server_response_send(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr, NX_RTSP_CLIENT_REQUEST *rtsp_client_request_ptr)
3550 {
3551 UINT       status = NX_SUCCESS;
3552 #ifdef FEATURE_NX_IPV6
3553 CHAR       temp_buffer[40]; /* The size for buffer to store an IPv6 address represented in ASCII. */
3554 #else
3555 CHAR       temp_buffer[11];
3556 #endif /* FEATURE_NX_IPV6 */
3557 UINT       temp_length;
3558 NX_PACKET *temp_packet_ptr;
3559 NX_PACKET *response_packet_ptr = rtsp_client_ptr -> nx_rtsp_client_response_packet;
3560 NX_PACKET_POOL *pool_ptr = rtsp_client_ptr -> nx_rtsp_client_server_ptr -> nx_rtsp_server_packet_pool;
3561 NXD_ADDRESS *source_ip_address;
3562 
3563     if (!response_packet_ptr)
3564     {
3565         return(NX_RTSP_SERVER_NO_PACKET);
3566     }
3567 
3568     switch (rtsp_client_request_ptr -> nx_rtsp_client_request_method)
3569     {
3570     case NX_RTSP_METHOD_OPTIONS:
3571     {
3572 
3573         /* Always support "OPTIONS, SETUP, PLAY, TEARDOWN".  */
3574         status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Public: OPTIONS, SETUP, PLAY, TEARDOWN"),
3575                                        pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3576 
3577         /* Check if other methods are supported.  */
3578         if (rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_describe_callback != NX_NULL)
3579         {
3580             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(", DESCRIBE"),
3581                                             pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3582         }
3583 
3584         if (rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_pause_callback != NX_NULL)
3585         {
3586             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(", PAUSE"),
3587                                             pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3588         }
3589 
3590         if (rtsp_server_ptr -> nx_rtsp_server_method_callbacks.nx_rtsp_server_method_set_parameter_callback != NX_NULL)
3591         {
3592             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(", SET_PARAMETER"),
3593                                             pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3594         }
3595 
3596         /* Add terminators.  */
3597         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n\r\n"),
3598                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3599 
3600         break;
3601     }
3602     case NX_RTSP_METHOD_DESCRIBE:
3603     {
3604 
3605         /* The details in DESCRIBE method are fulfilled in the function _nx_rtsp_server_sdp_set
3606            which is normally called in the function nx_rtsp_server_method_describe_callback.
3607            So, directly break here in order to skip adding terminators in the default branch.  */
3608         break;
3609     }
3610     case NX_RTSP_METHOD_SETUP:
3611     {
3612 
3613         /* Add "Session" header.  */
3614         status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Session: "),
3615                                        pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3616         temp_length = _nx_utility_uint_to_string(rtsp_client_ptr -> nx_rtsp_client_session_id, 10, temp_buffer, sizeof(temp_buffer));
3617         status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3618         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";timeout="),
3619                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3620         temp_length = _nx_utility_uint_to_string(NX_RTSP_SERVER_ACTIVITY_TIMEOUT, 10, temp_buffer, sizeof(temp_buffer));
3621         status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3622 
3623         /* Add "Transport" header.  */
3624         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\nTransport: RTP/AVP;"),
3625                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3626 
3627         /* Add unicast/multicast start words.  */
3628         if (rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode == NX_RTSP_TRANSPORT_MODE_UNICAST)
3629         {
3630             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("unicast;source="),
3631                                             pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3632 
3633             source_ip_address = &(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_ip_address);
3634         }
3635         else
3636         {
3637             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("multicast;destination="),
3638                                             pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3639 
3640             source_ip_address = &(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_ip_address);
3641         }
3642 
3643         /* Add source/destination IP address.  */
3644         if (rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V4)
3645         {
3646 #ifndef NX_DISABLE_IPV4
3647             temp_length = _nx_utility_uint_to_string(source_ip_address -> nxd_ip_address.v4 >> 24, 10, temp_buffer, sizeof(temp_buffer));
3648             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3649             status += nx_packet_data_append(response_packet_ptr, ".", 1, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3650             temp_length = _nx_utility_uint_to_string((source_ip_address -> nxd_ip_address.v4 >> 16) & 0xFF, 10, temp_buffer, sizeof(temp_buffer));
3651             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3652             status += nx_packet_data_append(response_packet_ptr, ".", 1, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3653             temp_length = _nx_utility_uint_to_string((source_ip_address -> nxd_ip_address.v4 >> 8) & 0xFF, 10, temp_buffer, sizeof(temp_buffer));
3654             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3655             status += nx_packet_data_append(response_packet_ptr, ".", 1, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3656             temp_length = _nx_utility_uint_to_string((source_ip_address -> nxd_ip_address.v4) & 0xFF, 10, temp_buffer, sizeof(temp_buffer));
3657             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3658 #else
3659             status = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
3660             break;
3661 #endif /* NX_DISABLE_IPV4 */
3662         }
3663         else if (rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6)
3664         {
3665 #ifdef FEATURE_NX_IPV6
3666             _nx_rtsp_server_ipv6_address_to_string(source_ip_address -> nxd_ip_address.v6, temp_buffer, sizeof(temp_buffer), &temp_length);
3667             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3668 #else
3669             status = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
3670             break;
3671 #endif /* FEATURE_NX_IPV6 */
3672         }
3673 
3674         if (rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode == NX_RTSP_TRANSPORT_MODE_UNICAST)
3675         {
3676             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";client_port="), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3677             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtp_port,
3678                                                      10, temp_buffer, sizeof(temp_buffer));
3679             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3680             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("-"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3681             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtcp_port,
3682                                                      10, temp_buffer, sizeof(temp_buffer));
3683             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3684 
3685             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";server_port="), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3686             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_rtp_port,
3687                                                      10, temp_buffer, sizeof(temp_buffer));
3688             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3689             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("-"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3690             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.server_rtcp_port,
3691                                                      10, temp_buffer, sizeof(temp_buffer));
3692             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3693 
3694             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";ssrc="), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3695             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.rtp_ssrc,
3696                                                      10, temp_buffer, sizeof(temp_buffer));
3697             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3698         }
3699         else
3700         {
3701             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";port="), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3702             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtp_port,
3703                                                      10, temp_buffer, sizeof(temp_buffer));
3704             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3705             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("-"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3706             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtcp_port,
3707                                                      10, temp_buffer, sizeof(temp_buffer));
3708             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3709 
3710             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";ttl="), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3711             temp_length = _nx_utility_uint_to_string(rtsp_client_request_ptr -> nx_rtsp_client_request_transport.multicast_ttl,
3712                                                      10, temp_buffer, sizeof(temp_buffer));
3713             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3714         }
3715 
3716         /* Add terminators.  */
3717         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n\r\n"),
3718                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3719 
3720         break;
3721     }
3722     case NX_RTSP_METHOD_PLAY:
3723     {
3724 
3725         /* If user has called nx_rtsp_server_rtp_info_set to set RTP-Info field,
3726            there is an extra character ',' appended to the end of the packet.  */
3727         temp_packet_ptr = response_packet_ptr;
3728 
3729 #ifndef NX_DISABLE_PACKET_CHAIN
3730         /* If the packet is chained, move to the last packet.  */
3731         if (response_packet_ptr -> nx_packet_last)
3732         {
3733             temp_packet_ptr = response_packet_ptr -> nx_packet_last;
3734         }
3735 #endif /* NX_DISABLE_PACKET_CHAIN */
3736 
3737         /* Remove the last character ','.  */
3738         if (*(temp_packet_ptr -> nx_packet_append_ptr - 1) == ',')
3739         {
3740             temp_packet_ptr -> nx_packet_append_ptr--;
3741             temp_packet_ptr -> nx_packet_length--;
3742         }
3743 
3744         /* Add terminators.  */
3745         status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
3746                                        pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3747     }
3748     /* fallthrough */
3749     case NX_RTSP_METHOD_PAUSE:
3750     {
3751         if ((rtsp_client_request_ptr -> nx_rtsp_client_request_method == NX_RTSP_METHOD_PLAY) ||
3752             (rtsp_client_ptr -> nx_rtsp_client_npt_start) || (rtsp_client_ptr -> nx_rtsp_client_npt_end))
3753         {
3754 
3755             /* Add "Range" header.  */
3756             status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Range: npt="),
3757                                            pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3758             temp_length = _nx_utility_uint_to_string((rtsp_client_ptr -> nx_rtsp_client_npt_start / 1000), 10, temp_buffer, sizeof(temp_buffer));
3759             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3760             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("."), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3761             temp_length = _nx_utility_uint_to_string((rtsp_client_ptr -> nx_rtsp_client_npt_start % 1000), 10, temp_buffer, sizeof(temp_buffer));
3762             status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3763             status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("-"), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3764 
3765             if (rtsp_client_ptr -> nx_rtsp_client_npt_end)
3766             {
3767                 temp_length = _nx_utility_uint_to_string((rtsp_client_ptr -> nx_rtsp_client_npt_end / 1000), 10, temp_buffer, sizeof(temp_buffer));
3768                 status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3769                 status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("."), pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3770                 temp_length = _nx_utility_uint_to_string((rtsp_client_ptr -> nx_rtsp_client_npt_end % 1000), 10, temp_buffer, sizeof(temp_buffer));
3771                 status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3772             }
3773 
3774             /* Add terminators.  */
3775             status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
3776                                            pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3777         }
3778 
3779         /* Add "Session" header.  */
3780         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("Session: "),
3781                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3782         temp_length = _nx_utility_uint_to_string(rtsp_client_ptr -> nx_rtsp_client_session_id, 10, temp_buffer, sizeof(temp_buffer));
3783         status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3784         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE(";timeout="),
3785                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3786         temp_length = _nx_utility_uint_to_string(NX_RTSP_SERVER_ACTIVITY_TIMEOUT, 10, temp_buffer, sizeof(temp_buffer));
3787         status += nx_packet_data_append(response_packet_ptr, temp_buffer, temp_length, pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3788 
3789         /* Add terminators.  */
3790         status += nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n\r\n"),
3791                                         pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3792 
3793         break;
3794     }
3795     default:
3796     {
3797 
3798         /* Add terminators.  */
3799         status = nx_packet_data_append(response_packet_ptr, NX_RTSP_SERVER_STRING_WITH_SIZE("\r\n"),
3800                                        pool_ptr, NX_RTSP_SERVER_PACKET_TIMEOUT);
3801 
3802         break;
3803     }
3804     }
3805 
3806     if (status == NX_SUCCESS)
3807     {
3808 
3809         /* Send the response message back.  */
3810         status = nx_tcp_socket_send(&rtsp_client_ptr -> nx_rtsp_client_socket, response_packet_ptr, NX_RTSP_SERVER_SEND_TIMEOUT);
3811     }
3812 
3813     /* Determine if the send was unsuccessful.  */
3814     if (status)
3815     {
3816 
3817         /* Release the packet.  */
3818         nx_packet_release(response_packet_ptr);
3819     }
3820 
3821     /* Clear the response packet pointer.  */
3822     rtsp_client_ptr -> nx_rtsp_client_response_packet = NX_NULL;
3823 
3824     return(status);
3825 }
3826 
3827 /**************************************************************************/
3828 /*                                                                        */
3829 /*  FUNCTION                                               RELEASE        */
3830 /*                                                                        */
3831 /*    _nx_rtsp_server_request_process                     PORTABLE C      */
3832 /*                                                           6.3.0        */
3833 /*  AUTHOR                                                                */
3834 /*                                                                        */
3835 /*    Wenhui Xie, Microsoft Corporation                                   */
3836 /*                                                                        */
3837 /*  DESCRIPTION                                                           */
3838 /*                                                                        */
3839 /*    This function processes RTSP requests.                              */
3840 /*                                                                        */
3841 /*  INPUT                                                                 */
3842 /*                                                                        */
3843 /*    rtsp_server_ptr                       Pointer to RTSP server        */
3844 /*                                                                        */
3845 /*  OUTPUT                                                                */
3846 /*                                                                        */
3847 /*    status                                Completion status             */
3848 /*                                                                        */
3849 /*  CALLS                                                                 */
3850 /*                                                                        */
3851 /*    _nx_rtsp_server_request_receive       Receive client request        */
3852 /*    _nx_rtsp_server_request_parse         Parse client request          */
3853 /*    _nx_rtsp_server_response_create       Create common response        */
3854 /*    _nx_rtsp_server_error_response_send   Send error response           */
3855 /*    _nx_rtsp_server_response_send         Send common response          */
3856 /*    nx_packet_release                     Release the packet            */
3857 /*                                                                        */
3858 /*  CALLED BY                                                             */
3859 /*                                                                        */
3860 /*    _nx_rtsp_server_thread_entry                                        */
3861 /*                                                                        */
3862 /*  RELEASE HISTORY                                                       */
3863 /*                                                                        */
3864 /*    DATE              NAME                      DESCRIPTION             */
3865 /*                                                                        */
3866 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
3867 /*                                                                        */
3868 /**************************************************************************/
_nx_rtsp_server_request_process(NX_RTSP_SERVER * rtsp_server_ptr)3869 static VOID _nx_rtsp_server_request_process(NX_RTSP_SERVER *rtsp_server_ptr)
3870 {
3871 UINT                   i;
3872 UINT                   status;
3873 NX_RTSP_CLIENT        *rtsp_client_ptr;
3874 NX_RTSP_SERVER_METHOD_CALLBACKS method_callbacks = rtsp_server_ptr -> nx_rtsp_server_method_callbacks;
3875 
3876 
3877     /* Now look for a socket that has receive data.  */
3878     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
3879     {
3880 
3881         /* Setup pointer to client structure.  */
3882         rtsp_client_ptr = &(rtsp_server_ptr -> nx_rtsp_server_client_list[i]);
3883 
3884         /* Now see if this socket has data.  */
3885         if (rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_receive_queue_count)
3886         {
3887 
3888             /* Attempt to read a packet from this socket.  */
3889             status = _nx_rtsp_server_request_receive(rtsp_server_ptr, rtsp_client_ptr);
3890 
3891             /* Check for no data present.  */
3892             if (status != NX_SUCCESS)
3893             {
3894 
3895                 /* Just continue the loop and look at the next socket.  */
3896                 continue;
3897             }
3898 
3899             /* Reset the client request activity timeout.  */
3900             rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout = NX_RTSP_SERVER_ACTIVITY_TIMEOUT;
3901 
3902             /* Set the pointer to the current Client request.  */
3903             rtsp_client_ptr -> nx_rtsp_client_request_ptr = &(rtsp_client_ptr -> nx_rtsp_client_request);
3904 
3905             /* Parse the client request.  */
3906             status = _nx_rtsp_server_request_parse(rtsp_client_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr);
3907 
3908             /* Check for error status.  */
3909             if (status != NX_SUCCESS)
3910             {
3911 
3912                 /* Release the request packet.  */
3913                 nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_request_packet);
3914                 rtsp_client_ptr -> nx_rtsp_client_request_packet = NX_NULL;
3915                 rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = 0;
3916 
3917                 /* Clear the pointer of Client request.  */
3918                 rtsp_client_ptr -> nx_rtsp_client_request_ptr = NX_NULL;
3919 
3920                 /* Just continue the loop and look at the next socket.  */
3921                 continue;
3922             }
3923 
3924             /* Create the response packet.  */
3925             status = _nx_rtsp_server_response_create(rtsp_server_ptr, rtsp_client_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr);
3926 
3927             /* Packet allocation failure.  */
3928             if (status != NX_SUCCESS)
3929             {
3930 
3931                 /* There is nothing we can do here. Ideally log this error event.  */
3932                 rtsp_server_ptr -> nx_rtsp_server_allocation_errors++;
3933 
3934                 /* Release the request packet.  */
3935                 nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_request_packet);
3936                 rtsp_client_ptr -> nx_rtsp_client_request_packet = NX_NULL;
3937                 rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = 0;
3938 
3939                 /* Clear the pointer of Client request.  */
3940                 rtsp_client_ptr -> nx_rtsp_client_request_ptr = NX_NULL;
3941 
3942                 /* At this point, just continue the loop and look at the next socket.  */
3943                 continue;
3944             }
3945 
3946             /* Set default response status code to 200 OK.  */
3947             rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_OK;
3948 
3949             switch (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_method)
3950             {
3951             case NX_RTSP_METHOD_OPTIONS:
3952             {
3953 
3954                 /* OPTIONS is always allowed and supported.  */
3955                 break;
3956             }
3957             case NX_RTSP_METHOD_DESCRIBE:
3958             {
3959                 if (method_callbacks.nx_rtsp_server_method_describe_callback == NX_NULL)
3960                 {
3961 
3962                     /* Method not installed, so we return "method not supported".  */
3963                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
3964 
3965                     break;
3966                 }
3967 
3968                 /* Invoke the actual callback routine.  */
3969                 status = method_callbacks.nx_rtsp_server_method_describe_callback
3970                          (rtsp_client_ptr,
3971                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
3972                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length);
3973 
3974                 if (status != NX_SUCCESS)
3975                 {
3976 
3977                     /* Internal error occurs.  */
3978                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
3979                 }
3980 
3981                 break;
3982             }
3983             case NX_RTSP_METHOD_SETUP:
3984             {
3985 
3986                 /* The callbacks for SETUP, PLAY and TEARDOWN are required to be set and
3987                    we have checked this in _nx_rtsp_server_start() function.  */
3988 
3989                 /* If session ID is present, we need to verify session ID.  */
3990                 if (rtsp_client_ptr -> nx_rtsp_client_session_id &&
3991                     (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_session_id != rtsp_client_ptr -> nx_rtsp_client_session_id))
3992                 {
3993 
3994                     /* Session not found.  */
3995                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
3996                     break;
3997                 }
3998 
3999                 if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr == NX_NULL)
4000                 {
4001 
4002                     /* No media specified in the request. Invalid case.  */
4003                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4004                     break;
4005                 }
4006                 else if ((rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_transport.transport_mode == NX_RTSP_TRANSPORT_MODE_UNICAST) &&
4007                          ((rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtp_port == 0) ||
4008                           (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_transport.client_rtcp_port == 0)))
4009                 {
4010 
4011                     /* Invalid client port.  */
4012                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_UNSUPPORTED_TRANSPORT;
4013                     break;
4014                 }
4015 
4016                 status = method_callbacks.nx_rtsp_server_method_setup_callback
4017                          (rtsp_client_ptr,
4018                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
4019                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length,
4020                           &(rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_transport));
4021 
4022                 /* If callback returns "SUCCESS".  */
4023                 if (status == NX_SUCCESS)
4024                 {
4025                     if (rtsp_client_ptr -> nx_rtsp_client_state == NX_RTSP_STATE_INIT)
4026                     {
4027 
4028                         /* Set client state to ready.  */
4029                         rtsp_client_ptr -> nx_rtsp_client_state = NX_RTSP_STATE_READY;
4030                     }
4031 
4032                     if (rtsp_client_ptr -> nx_rtsp_client_session_id == 0)
4033                     {
4034 
4035                         /* Remember the session ID for future validation.  */
4036                         rtsp_client_ptr -> nx_rtsp_client_session_id = (ULONG)NX_RAND();
4037                     }
4038                 }
4039                 else
4040                 {
4041 
4042                     /* Internal error occurs.  */
4043                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
4044                 }
4045 
4046                 break;
4047             }
4048             case NX_RTSP_METHOD_PLAY:
4049             {
4050 
4051                 /* The callbacks for SETUP, PLAY and TEARDOWN are required to be set and
4052                    we have checked this in _nx_rtsp_server_start() function.  */
4053 
4054                 if (!(rtsp_client_ptr -> nx_rtsp_client_session_id) ||
4055                     (rtsp_client_ptr -> nx_rtsp_client_session_id != rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_session_id))
4056                 {
4057 
4058                     /* Session not found.  */
4059                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4060 
4061                     break;
4062                 }
4063 
4064                 if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr == NX_NULL)
4065                 {
4066 
4067                     /* No media specified in the request. Invalid case.  */
4068                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4069                     break;
4070                 }
4071 
4072                 /* Reset the npt start and end time.  */
4073                 rtsp_client_ptr -> nx_rtsp_client_npt_start = 0;
4074                 rtsp_client_ptr -> nx_rtsp_client_npt_end = 0;
4075 
4076                 status = method_callbacks.nx_rtsp_server_method_play_callback
4077                          (rtsp_client_ptr,
4078                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
4079                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length,
4080                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_range_ptr,
4081                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_range_length);
4082 
4083                 /* If callback returns "SUCCESS".  */
4084                 if (status == NX_SUCCESS)
4085                 {
4086 
4087                     /* Set client state to playing.  */
4088                     rtsp_client_ptr -> nx_rtsp_client_state = NX_RTSP_STATE_PLAYING;
4089                 }
4090                 else
4091                 {
4092 
4093                     /* Internal error occurs.  */
4094                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
4095                 }
4096 
4097                 break;
4098             }
4099             case NX_RTSP_METHOD_PAUSE:
4100             {
4101                 if (method_callbacks.nx_rtsp_server_method_pause_callback == NX_NULL)
4102                 {
4103 
4104                     /* Method not installed, so we return "method not supported".  */
4105                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
4106 
4107                     break;
4108                 }
4109 
4110                 /* Validate Session ID.  */
4111                 if (!(rtsp_client_ptr -> nx_rtsp_client_session_id) ||
4112                     (rtsp_client_ptr -> nx_rtsp_client_session_id != rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_session_id))
4113                 {
4114 
4115                     /* Session not found.  */
4116                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4117 
4118                     break;
4119                 }
4120 
4121                 if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr == NX_NULL)
4122                 {
4123 
4124                     /* No media specified in the request. Invalid case.  */
4125                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4126                     break;
4127                 }
4128 
4129                 /* Reset the npt start and end time.  */
4130                 rtsp_client_ptr -> nx_rtsp_client_npt_start = 0;
4131                 rtsp_client_ptr -> nx_rtsp_client_npt_end = 0;
4132 
4133                 status = method_callbacks.nx_rtsp_server_method_pause_callback
4134                          (rtsp_client_ptr,
4135                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
4136                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length,
4137                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_range_ptr,
4138                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_range_length);
4139 
4140                 /* If callback returns "SUCCESS".  */
4141                 if (status == NX_SUCCESS)
4142                 {
4143 
4144                     /* Set client state to ready.  */
4145                     rtsp_client_ptr -> nx_rtsp_client_state = NX_RTSP_STATE_READY;
4146                 }
4147                 else
4148                 {
4149 
4150                     /* Internal error occurs.  */
4151                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
4152                 }
4153 
4154                 break;
4155             }
4156             case NX_RTSP_METHOD_TEARDOWN:
4157             {
4158 
4159                 /* The callbacks for SETUP, PLAY and TEARDOWN are required to be set and
4160                    we have checked this in _nx_rtsp_server_start() function.  */
4161 
4162                 /* Validate session ID.  */
4163                 if (!(rtsp_client_ptr -> nx_rtsp_client_session_id) ||
4164                     (rtsp_client_ptr -> nx_rtsp_client_session_id != rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_session_id))
4165                 {
4166 
4167                     /* Session not found.  */
4168                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4169 
4170                     break;
4171                 }
4172 
4173                 if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr == NX_NULL)
4174                 {
4175 
4176                     /* No media specified in the request. Invalid case.  */
4177                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4178                     break;
4179                 }
4180 
4181                 status = method_callbacks.nx_rtsp_server_method_teardown_callback
4182                          (rtsp_client_ptr,
4183                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
4184                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length);
4185 
4186 
4187                 /* If got positive response from media handler.  */
4188                 if (status == NX_SUCCESS)
4189                 {
4190 
4191                     /* Set client state to init.  */
4192                     rtsp_client_ptr -> nx_rtsp_client_state = NX_RTSP_STATE_INIT;
4193 
4194                     /* Clear the session ID.  */
4195                     rtsp_client_ptr -> nx_rtsp_client_session_id = 0;
4196                 }
4197                 else
4198                 {
4199 
4200                     /* Internal error occurs.  */
4201                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
4202                 }
4203 
4204                 break;
4205             }
4206             case NX_RTSP_METHOD_SET_PARAMETER:
4207             {
4208                 if (method_callbacks.nx_rtsp_server_method_set_parameter_callback == NULL)
4209                 {
4210 
4211                     /* Method not installed, so we return "method not supported".  */
4212                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
4213 
4214                     break;
4215                 }
4216 
4217                 /* Validate session ID.  */
4218                 if (!(rtsp_client_ptr -> nx_rtsp_client_session_id) ||
4219                     (rtsp_client_ptr -> nx_rtsp_client_session_id != rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_session_id))
4220                 {
4221 
4222                     /* Session not found.  */
4223                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4224 
4225                     break;
4226                 }
4227 
4228                 if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr == NX_NULL)
4229                 {
4230 
4231                     /* No media specified in the request. Invalid case.  */
4232                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_SESSION_NOT_FOUND;
4233                     break;
4234                 }
4235 
4236                 status = method_callbacks.nx_rtsp_server_method_set_parameter_callback
4237                          (rtsp_client_ptr,
4238                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_ptr,
4239                           rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_uri_length,
4240                           (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_append_ptr - rtsp_client_ptr -> nx_rtsp_client_request_content_length),
4241                           rtsp_client_ptr -> nx_rtsp_client_request_content_length);
4242 
4243                 /* If callback returns "SUCCESS".  */
4244                 if (status)
4245                 {
4246 
4247                     /* Internal error occurs.  */
4248                     rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR;
4249                 }
4250 
4251                 break;
4252             }
4253             default:
4254             {
4255 
4256                 /* Method not installed, so we return "NOT IMPLEMENTED".  */
4257                 rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code = NX_RTSP_STATUS_CODE_NOT_IMPLEMENTED;
4258 
4259                 break;
4260             }
4261             }
4262 
4263             /* Send the response.  */
4264             if (rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code >= 300)
4265             {
4266 
4267                 /* Handle error response.  */
4268                 _nx_rtsp_server_error_response_send(rtsp_client_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr -> nx_rtsp_client_request_response_code);
4269             }
4270             else
4271             {
4272                 _nx_rtsp_server_response_send(rtsp_server_ptr, rtsp_client_ptr, rtsp_client_ptr -> nx_rtsp_client_request_ptr);
4273             }
4274 
4275             /* Release the request packet.  */
4276             nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_request_packet);
4277             rtsp_client_ptr -> nx_rtsp_client_request_packet = NX_NULL;
4278             rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = 0;
4279 
4280             /* Clear the pointer of Client request.  */
4281             rtsp_client_ptr -> nx_rtsp_client_request_ptr = NX_NULL;
4282         }
4283     }
4284 }
4285 
4286 /**************************************************************************/
4287 /*                                                                        */
4288 /*  FUNCTION                                               RELEASE        */
4289 /*                                                                        */
4290 /*    _nx_rtsp_server_connect_process                     PORTABLE C      */
4291 /*                                                           6.3.0        */
4292 /*  AUTHOR                                                                */
4293 /*                                                                        */
4294 /*    Wenhui Xie, Microsoft Corporation                                   */
4295 /*                                                                        */
4296 /*  DESCRIPTION                                                           */
4297 /*                                                                        */
4298 /*    This function processes connections for multiple sessions.          */
4299 /*                                                                        */
4300 /*  INPUT                                                                 */
4301 /*                                                                        */
4302 /*    rtsp_server_ptr                       Pointer to RTSP server        */
4303 /*                                                                        */
4304 /*  OUTPUT                                                                */
4305 /*                                                                        */
4306 /*    None                                                                */
4307 /*                                                                        */
4308 /*  CALLS                                                                 */
4309 /*                                                                        */
4310 /*    nx_tcp_server_socket_accept           Accept incoming TCP request   */
4311 /*    nx_tcp_server_socket_unaccept         Clear accepted socket         */
4312 /*    nx_tcp_server_socket_relisten         Re-listen on free socket      */
4313 /*                                                                        */
4314 /*  CALLED BY                                                             */
4315 /*                                                                        */
4316 /*    _nx_rtsp_server_thread_entry                                        */
4317 /*                                                                        */
4318 /*  RELEASE HISTORY                                                       */
4319 /*                                                                        */
4320 /*    DATE              NAME                      DESCRIPTION             */
4321 /*                                                                        */
4322 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4323 /*                                                                        */
4324 /**************************************************************************/
_nx_rtsp_server_connect_process(NX_RTSP_SERVER * rtsp_server_ptr)4325 static VOID _nx_rtsp_server_connect_process(NX_RTSP_SERVER *rtsp_server_ptr)
4326 {
4327 UINT            i;
4328 UINT            status;
4329 NX_RTSP_CLIENT *client_ptr;
4330 
4331 
4332     /* One of the control ports is in the processing of connection.
4333        Search the connections to see which one.  */
4334     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
4335     {
4336 
4337         /* Setup pointer to client structure.  */
4338         client_ptr =  &(rtsp_server_ptr -> nx_rtsp_server_client_list[i]);
4339 
4340         /* Now see if this socket was the one that is in being connected.  */
4341         if ((client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_state > NX_TCP_CLOSED) &&
4342             (client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_state < NX_TCP_ESTABLISHED) &&
4343             (client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_connect_port))
4344         {
4345 
4346             /* Yes, we have found the socket being connected.  */
4347 
4348             /* Attempt to accept on this socket.  */
4349             status = nx_tcp_server_socket_accept(&(client_ptr -> nx_rtsp_client_socket), NX_RTSP_SERVER_ACCEPT_TIMEOUT);
4350 
4351             /* Determine if it is successful.  */
4352             if (status)
4353             {
4354 
4355                 /* Not successful, simply unaccept on this socket.  */
4356                 nx_tcp_server_socket_unaccept(&(client_ptr -> nx_rtsp_client_socket));
4357             }
4358             else
4359             {
4360 
4361                 /* Reset the client request activity timeout.  */
4362                 client_ptr -> nx_rtsp_client_request_activity_timeout =  NX_RTSP_SERVER_ACTIVITY_TIMEOUT;
4363 
4364                 /* Set the client as valid.  */
4365                 client_ptr -> nx_rtsp_client_valid = NX_TRUE;
4366 
4367                 /* Store the RTSP server pointer.  */
4368                 client_ptr -> nx_rtsp_client_server_ptr = rtsp_server_ptr;
4369 
4370                 /* Update the connected client count.  */
4371                 rtsp_server_ptr -> nx_rtsp_server_connected_client_count++;
4372             }
4373 
4374             /* In any case break out of the loop when we find a connection - there can only be one
4375                at a time!  */
4376             break;
4377         }
4378     }
4379 
4380     /* Now look for a client that is valid to relisten on.  */
4381     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
4382     {
4383 
4384         /* Setup pointer to client request structure.  */
4385         client_ptr =  &(rtsp_server_ptr -> nx_rtsp_server_client_list[i]);
4386 
4387         /* Now see if this socket is closed.  */
4388         if ((client_ptr -> nx_rtsp_client_valid == NX_FALSE) &&
4389             (client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_state == NX_TCP_CLOSED))
4390         {
4391 
4392             /* Relisten on this socket.  */
4393             status =  nx_tcp_server_socket_relisten(rtsp_server_ptr -> nx_rtsp_server_ip_ptr, rtsp_server_ptr -> nx_rtsp_server_port,
4394                                                     &(client_ptr -> nx_rtsp_client_socket));
4395 
4396             /* Check for bad status.  */
4397             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
4398             {
4399 
4400                 /* Increment the error count and keep trying.  */
4401                 rtsp_server_ptr -> nx_rtsp_server_relisten_errors++;
4402                 continue;
4403             }
4404 
4405             /* Break out of loop.  */
4406             break;
4407         }
4408     }
4409 }
4410 
4411 /**************************************************************************/
4412 /*                                                                        */
4413 /*  FUNCTION                                               RELEASE        */
4414 /*                                                                        */
4415 /*    _nx_rtsp_server_disconnect_process                  PORTABLE C      */
4416 /*                                                           6.3.0        */
4417 /*  AUTHOR                                                                */
4418 /*                                                                        */
4419 /*    Wenhui Xie, Microsoft Corporation                                   */
4420 /*                                                                        */
4421 /*  DESCRIPTION                                                           */
4422 /*                                                                        */
4423 /*    This function processes disconnect for multiple sessions.           */
4424 /*                                                                        */
4425 /*  INPUT                                                                 */
4426 /*                                                                        */
4427 /*    rtsp_server_ptr                       Pointer to RTSP server        */
4428 /*                                                                        */
4429 /*  OUTPUT                                                                */
4430 /*                                                                        */
4431 /*    None                                                                */
4432 /*                                                                        */
4433 /*  CALLS                                                                 */
4434 /*                                                                        */
4435 /*    _nx_rtsp_server_disconnect             Disconnect from client       */
4436 /*                                                                        */
4437 /*  CALLED BY                                                             */
4438 /*                                                                        */
4439 /*    _nx_rtsp_server_thread_entry                                        */
4440 /*                                                                        */
4441 /*  RELEASE HISTORY                                                       */
4442 /*                                                                        */
4443 /*    DATE              NAME                      DESCRIPTION             */
4444 /*                                                                        */
4445 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4446 /*                                                                        */
4447 /**************************************************************************/
_nx_rtsp_server_disconnect_process(NX_RTSP_SERVER * rtsp_server_ptr)4448 static VOID _nx_rtsp_server_disconnect_process(NX_RTSP_SERVER *rtsp_server_ptr)
4449 {
4450 UINT            i;
4451 NX_RTSP_CLIENT *rtsp_client_ptr;
4452 
4453 
4454     /* Examine all the client structures.  */
4455     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
4456     {
4457 
4458         /* Setup pointer to client structure.  */
4459         rtsp_client_ptr =  &(rtsp_server_ptr -> nx_rtsp_server_client_list[i]);
4460 
4461         /* Determine if this socket is in a disconnect state.  */
4462         if (rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_state > NX_TCP_ESTABLISHED)
4463         {
4464 
4465             /* Yes, this socket needs to be torn down.  */
4466 
4467             /* Increment the number of disconnection requests.  */
4468             rtsp_server_ptr -> nx_rtsp_server_disconnection_requests++;
4469 
4470             /* Disconnect the socket.  */
4471             _nx_rtsp_server_disconnect(rtsp_server_ptr, rtsp_client_ptr);
4472         }
4473     }
4474 }
4475 
4476 /**************************************************************************/
4477 /*                                                                        */
4478 /*  FUNCTION                                               RELEASE        */
4479 /*                                                                        */
4480 /*    _nx_rtsp_server_timeout_process                     PORTABLE C      */
4481 /*                                                           6.3.0        */
4482 /*  AUTHOR                                                                */
4483 /*                                                                        */
4484 /*    Wenhui Xie, Microsoft Corporation                                   */
4485 /*                                                                        */
4486 /*  DESCRIPTION                                                           */
4487 /*                                                                        */
4488 /*    This function processes timeout event.                              */
4489 /*                                                                        */
4490 /*  INPUT                                                                 */
4491 /*                                                                        */
4492 /*    rtsp_server_ptr                       Pointer to RTSP server        */
4493 /*                                                                        */
4494 /*  OUTPUT                                                                */
4495 /*                                                                        */
4496 /*    None                                                                */
4497 /*                                                                        */
4498 /*  CALLS                                                                 */
4499 /*                                                                        */
4500 /*    _nx_rtsp_server_disconnect             Disconnect from client       */
4501 /*                                                                        */
4502 /*  CALLED BY                                                             */
4503 /*                                                                        */
4504 /*    _nx_rtsp_server_thread_entry                                        */
4505 /*                                                                        */
4506 /*  RELEASE HISTORY                                                       */
4507 /*                                                                        */
4508 /*    DATE              NAME                      DESCRIPTION             */
4509 /*                                                                        */
4510 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4511 /*                                                                        */
4512 /**************************************************************************/
_nx_rtsp_server_timeout_process(NX_RTSP_SERVER * rtsp_server_ptr)4513 static VOID _nx_rtsp_server_timeout_process(NX_RTSP_SERVER *rtsp_server_ptr)
4514 {
4515 UINT            i;
4516 NX_RTSP_CLIENT *rtsp_client_ptr;
4517 
4518 
4519     /* Examine all the client structures.  */
4520     for (i = 0; i < NX_RTSP_SERVER_MAX_CLIENTS; i++)
4521     {
4522 
4523         /* Setup pointer to client structure.  */
4524         rtsp_client_ptr =  &(rtsp_server_ptr -> nx_rtsp_server_client_list[i]);
4525 
4526         /* Skip the socket that is not used.  */
4527         if (rtsp_client_ptr -> nx_rtsp_client_socket.nx_tcp_socket_state <= NX_TCP_LISTEN_STATE)
4528         {
4529             continue;
4530         }
4531 
4532         /* Skip the inactive client.  */
4533         if (rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout == 0)
4534         {
4535             continue;
4536         }
4537 
4538         /* Decrease the timer count.  */
4539         rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout--;
4540 
4541         /* Check if the client is timeout.  */
4542         if (rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout == 0)
4543         {
4544 
4545             /* Disconnect the socket.  */
4546             _nx_rtsp_server_disconnect(rtsp_server_ptr, rtsp_client_ptr);
4547         }
4548     }
4549 }
4550 
4551 /**************************************************************************/
4552 /*                                                                        */
4553 /*  FUNCTION                                               RELEASE        */
4554 /*                                                                        */
4555 /*    _nx_rtsp_server_request_present                      PORTABLE C     */
4556 /*                                                           6.3.0        */
4557 /*  AUTHOR                                                                */
4558 /*                                                                        */
4559 /*    Wenhui Xie, Microsoft Corporation                                   */
4560 /*                                                                        */
4561 /*  DESCRIPTION                                                           */
4562 /*                                                                        */
4563 /*    This function handles all RTSP client commands received on          */
4564 /*    the control socket.                                                 */
4565 /*                                                                        */
4566 /*                                                                        */
4567 /*  INPUT                                                                 */
4568 /*                                                                        */
4569 /*    request_socket_ptr                    Socket event occurred         */
4570 /*                                                                        */
4571 /*  OUTPUT                                                                */
4572 /*                                                                        */
4573 /*    None                                                                */
4574 /*                                                                        */
4575 /*  CALLS                                                                 */
4576 /*                                                                        */
4577 /*    tx_event_flags_set                    Set events for server thread  */
4578 /*                                                                        */
4579 /*  CALLED BY                                                             */
4580 /*                                                                        */
4581 /*    NetX                                  NetX receive packet callback  */
4582 /*                                                                        */
4583 /*  RELEASE HISTORY                                                       */
4584 /*                                                                        */
4585 /*    DATE              NAME                      DESCRIPTION             */
4586 /*                                                                        */
4587 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4588 /*                                                                        */
4589 /**************************************************************************/
_nx_rtsp_server_request_present(NX_TCP_SOCKET * request_socket_ptr)4590 static VOID _nx_rtsp_server_request_present(NX_TCP_SOCKET *request_socket_ptr)
4591 {
4592 
4593 NX_RTSP_SERVER *server_ptr;
4594 
4595 
4596     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
4597     server_ptr = request_socket_ptr -> nx_tcp_socket_reserved_ptr;
4598 
4599     /* Set the request event flag.  */
4600     tx_event_flags_set(&(server_ptr -> nx_rtsp_server_event_flags), NX_RTSP_SERVER_REQUEST_EVENT, TX_OR);
4601 }
4602 
4603 /**************************************************************************/
4604 /*                                                                        */
4605 /*  FUNCTION                                               RELEASE        */
4606 /*                                                                        */
4607 /*    _nx_rtsp_server_connect_present                      PORTABLE C     */
4608 /*                                                           6.3.0        */
4609 /*  AUTHOR                                                                */
4610 /*                                                                        */
4611 /*    Wenhui Xie, Microsoft Corporation                                   */
4612 /*                                                                        */
4613 /*  DESCRIPTION                                                           */
4614 /*                                                                        */
4615 /*    This function handles all RTSP client connections received on       */
4616 /*    the control socket.                                                 */
4617 /*                                                                        */
4618 /*                                                                        */
4619 /*  INPUT                                                                 */
4620 /*                                                                        */
4621 /*    request_socket_ptr                    Socket event occurred         */
4622 /*    port                                  Port the connection occurred  */
4623 /*                                                                        */
4624 /*  OUTPUT                                                                */
4625 /*                                                                        */
4626 /*    None                                                                */
4627 /*                                                                        */
4628 /*  CALLS                                                                 */
4629 /*                                                                        */
4630 /*    tx_event_flags_set                    Set events for server thread  */
4631 /*                                                                        */
4632 /*  CALLED BY                                                             */
4633 /*                                                                        */
4634 /*    NetX                                  NetX connect callback         */
4635 /*                                                                        */
4636 /*  RELEASE HISTORY                                                       */
4637 /*                                                                        */
4638 /*    DATE              NAME                      DESCRIPTION             */
4639 /*                                                                        */
4640 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4641 /*                                                                        */
4642 /**************************************************************************/
_nx_rtsp_server_connect_present(NX_TCP_SOCKET * request_socket_ptr,UINT port)4643 static VOID  _nx_rtsp_server_connect_present(NX_TCP_SOCKET *request_socket_ptr, UINT port)
4644 {
4645 NX_RTSP_SERVER *server_ptr;
4646 
4647 
4648     NX_PARAMETER_NOT_USED(port);
4649 
4650     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
4651     server_ptr =  request_socket_ptr -> nx_tcp_socket_reserved_ptr;
4652 
4653     /* Set the connect event flag.  */
4654     tx_event_flags_set(&(server_ptr -> nx_rtsp_server_event_flags), NX_RTSP_SERVER_CONNECT_EVENT, TX_OR);
4655 }
4656 
4657 /**************************************************************************/
4658 /*                                                                        */
4659 /*  FUNCTION                                               RELEASE        */
4660 /*                                                                        */
4661 /*    _nx_rtsp_server_disconnect_present                   PORTABLE C     */
4662 /*                                                           6.3.0        */
4663 /*  AUTHOR                                                                */
4664 /*                                                                        */
4665 /*    Wenhui Xie, Microsoft Corporation                                   */
4666 /*                                                                        */
4667 /*  DESCRIPTION                                                           */
4668 /*                                                                        */
4669 /*    This function notifies the RTSP server thread of client disconnects */
4670 /*    of the control socket.                                              */
4671 /*                                                                        */
4672 /*                                                                        */
4673 /*  INPUT                                                                 */
4674 /*                                                                        */
4675 /*    request_socket_ptr                    Socket event occurred         */
4676 /*                                                                        */
4677 /*  OUTPUT                                                                */
4678 /*                                                                        */
4679 /*    None                                                                */
4680 /*                                                                        */
4681 /*  CALLS                                                                 */
4682 /*                                                                        */
4683 /*    tx_event_flags_set                    Set events for server thread  */
4684 /*                                                                        */
4685 /*  CALLED BY                                                             */
4686 /*                                                                        */
4687 /*    NetX                                  NetX connect callback         */
4688 /*                                                                        */
4689 /*  RELEASE HISTORY                                                       */
4690 /*                                                                        */
4691 /*    DATE              NAME                      DESCRIPTION             */
4692 /*                                                                        */
4693 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4694 /*                                                                        */
4695 /**************************************************************************/
_nx_rtsp_server_disconnect_present(NX_TCP_SOCKET * request_socket_ptr)4696 static VOID _nx_rtsp_server_disconnect_present(NX_TCP_SOCKET *request_socket_ptr)
4697 {
4698 NX_RTSP_SERVER *server_ptr;
4699 
4700 
4701     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
4702     server_ptr =  request_socket_ptr -> nx_tcp_socket_reserved_ptr;
4703 
4704     /* Set the disconnect event flag.  */
4705     tx_event_flags_set(&(server_ptr -> nx_rtsp_server_event_flags), NX_RTSP_SERVER_DISCONNECT_EVENT, TX_OR);
4706 }
4707 
4708 /**************************************************************************/
4709 /*                                                                        */
4710 /*  FUNCTION                                               RELEASE        */
4711 /*                                                                        */
4712 /*    _nx_rtsp_server_timeout                              PORTABLE C     */
4713 /*                                                           6.3.0        */
4714 /*  AUTHOR                                                                */
4715 /*                                                                        */
4716 /*    Wenhui Xie, Microsoft Corporation                                   */
4717 /*                                                                        */
4718 /*  DESCRIPTION                                                           */
4719 /*                                                                        */
4720 /*    This internal function is invoked whenever the internal timeout     */
4721 /*    timer expires, and is passed into tx_timer_create as the callback.  */
4722 /*                                                                        */
4723 /*                                                                        */
4724 /*  INPUT                                                                 */
4725 /*                                                                        */
4726 /*    rtsp_server_address                   Pointer to RTSP server        */
4727 /*                                                                        */
4728 /*  OUTPUT                                                                */
4729 /*                                                                        */
4730 /*    None                                                                */
4731 /*                                                                        */
4732 /*  CALLS                                                                 */
4733 /*                                                                        */
4734 /*    tx_event_flags_set                    Set events for server thread  */
4735 /*                                                                        */
4736 /*  CALLED BY                                                             */
4737 /*                                                                        */
4738 /*    ThreadX                                                             */
4739 /*                                                                        */
4740 /*  RELEASE HISTORY                                                       */
4741 /*                                                                        */
4742 /*    DATE              NAME                      DESCRIPTION             */
4743 /*                                                                        */
4744 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4745 /*                                                                        */
4746 /**************************************************************************/
_nx_rtsp_server_timeout(ULONG rtsp_server_address)4747 static VOID _nx_rtsp_server_timeout(ULONG rtsp_server_address)
4748 {
4749 NX_RTSP_SERVER *rtsp_server_ptr = (NX_RTSP_SERVER *)rtsp_server_address;
4750 
4751 
4752     /* Set the timeout event flag. */
4753     tx_event_flags_set(&(rtsp_server_ptr -> nx_rtsp_server_event_flags), NX_RTSP_SERVER_TIMEOUT_EVENT, TX_OR);
4754 }
4755 
4756 /**************************************************************************/
4757 /*                                                                        */
4758 /*  FUNCTION                                               RELEASE        */
4759 /*                                                                        */
4760 /*    _nx_rtsp_server_disconnect                           PORTABLE C     */
4761 /*                                                           6.3.0        */
4762 /*  AUTHOR                                                                */
4763 /*                                                                        */
4764 /*    Wenhui Xie, Microsoft Corporation                                   */
4765 /*                                                                        */
4766 /*  DESCRIPTION                                                           */
4767 /*                                                                        */
4768 /*    This function disconnects a client which is disconnected or timeout.*/
4769 /*                                                                        */
4770 /*                                                                        */
4771 /*  INPUT                                                                 */
4772 /*                                                                        */
4773 /*    rtsp_server_ptr                       Pointer to RTSP server        */
4774 /*    rtsp_client_ptr                       Pointer to RTSP client        */
4775 /*                                                                        */
4776 /*  OUTPUT                                                                */
4777 /*                                                                        */
4778 /*    None                                                                */
4779 /*                                                                        */
4780 /*  CALLS                                                                 */
4781 /*                                                                        */
4782 /*    nx_tcp_socket_disconnect              Disconnect TCP socket         */
4783 /*    nx_tcp_server_socket_unaccept         Clear accepted socket         */
4784 /*    nx_packet_release                     Release the packet            */
4785 /*    nx_tcp_server_socket_relisten         Re-listen on free socket      */
4786 /*                                                                        */
4787 /*  CALLED BY                                                             */
4788 /*                                                                        */
4789 /*    _nx_rtsp_server_disconnect_process                                  */
4790 /*    _nx_rtsp_server_timeout_process                                     */
4791 /*                                                                        */
4792 /*  RELEASE HISTORY                                                       */
4793 /*                                                                        */
4794 /*    DATE              NAME                      DESCRIPTION             */
4795 /*                                                                        */
4796 /*  10-31-2023     Wenhui Xie               Initial Version 6.3.0         */
4797 /*                                                                        */
4798 /**************************************************************************/
_nx_rtsp_server_disconnect(NX_RTSP_SERVER * rtsp_server_ptr,NX_RTSP_CLIENT * rtsp_client_ptr)4799 static VOID _nx_rtsp_server_disconnect(NX_RTSP_SERVER *rtsp_server_ptr, NX_RTSP_CLIENT *rtsp_client_ptr)
4800 {
4801 
4802     /* Disable the client request activity timeout.  */
4803     rtsp_client_ptr -> nx_rtsp_client_request_activity_timeout = 0;
4804 
4805     /* Now disconnect the socket.  */
4806     nx_tcp_socket_disconnect(&(rtsp_client_ptr -> nx_rtsp_client_socket), NX_NO_WAIT);
4807 
4808     /* Unaccept the server socket.  */
4809     nx_tcp_server_socket_unaccept(&(rtsp_client_ptr -> nx_rtsp_client_socket));
4810 
4811     /* Check to see if a packet is queued up.  */
4812     if (rtsp_client_ptr -> nx_rtsp_client_request_packet)
4813     {
4814 
4815         /* Yes, release it!  */
4816         nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_request_packet);
4817         rtsp_client_ptr -> nx_rtsp_client_request_packet = NX_NULL;
4818         rtsp_client_ptr -> nx_rtsp_client_request_bytes_total = 0;
4819     }
4820 
4821     /* Check to see if a packet is queued up.  */
4822     if (rtsp_client_ptr -> nx_rtsp_client_response_packet)
4823     {
4824 
4825         /* Yes, release it!  */
4826         nx_packet_release(rtsp_client_ptr -> nx_rtsp_client_response_packet);
4827         rtsp_client_ptr -> nx_rtsp_client_response_packet = NX_NULL;
4828     }
4829 
4830     /* Invoke the disconnect callback.  */
4831     if ((rtsp_server_ptr -> nx_rtsp_server_disconnect_callback) &&
4832         (rtsp_client_ptr -> nx_rtsp_client_state > NX_RTSP_STATE_INIT))
4833     {
4834         rtsp_server_ptr -> nx_rtsp_server_disconnect_callback(rtsp_client_ptr);
4835     }
4836 
4837     /* Relisten on this socket.  */
4838     nx_tcp_server_socket_relisten(rtsp_server_ptr -> nx_rtsp_server_ip_ptr, rtsp_server_ptr -> nx_rtsp_server_port,
4839                                   &(rtsp_client_ptr -> nx_rtsp_client_socket));
4840 
4841     /* Clear the session ID.  */
4842     rtsp_client_ptr -> nx_rtsp_client_session_id = 0;
4843 
4844     /* Reset client valid status.  */
4845     rtsp_client_ptr -> nx_rtsp_client_valid = NX_FALSE;
4846 
4847     /* Reset client state.  */
4848     rtsp_client_ptr -> nx_rtsp_client_state = NX_RTSP_STATE_INIT;
4849 
4850     /* Update the connected client count.  */
4851     rtsp_server_ptr -> nx_rtsp_server_connected_client_count--;
4852 }
4853 
4854