
    qi%                         d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ e G d
 d             Ze G d d             Ze G d d             Z G d de      Z G d d      Zy)zSmallWebRTC request handler for managing peer connections.

This module provides a client for handling web requests and managing WebRTC connections.
    N)	dataclass)Enum)Any	AwaitableCallableDictListOptional)candidate_from_sdp)HTTPException)logger)	IceServerSmallWebRTCConnectionc                   x    e Zd ZU dZeed<   eed<   dZee   ed<   dZee	   ed<   dZ
ee   ed<   edefd	       Zy)
SmallWebRTCRequesta  Small WebRTC transport session arguments for the runner.

    Parameters:
        sdp: The SDP string (Session Description Protocol).
        type: The type of the SDP, either "offer" or "answer".
        pc_id: Optional identifier for the peer connection.
        restart_pc: Optional whether to restart the peer connection.
        request_data: Optional custom data sent by the customer.
    sdptypeNpc_id
restart_pcrequest_datadatac                 J    d|v rd|vr|j                  d      |d<    | di |S )z@Accept both snake_case and camelCase for the request_data field.requestDatar    )pop)clsr   s     `/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/smallwebrtc/request_handler.py	from_dictzSmallWebRTCRequest.from_dict*   s2     D ^4%?#'88M#:D {T{    )__name__
__module____qualname____doc__str__annotations__r   r
   r   boolr   r   classmethoddictr   r   r   r   r   r      sV     
H
IE8C=!%J%"&L(3-&T  r   r   c                   0    e Zd ZU dZeed<   eed<   eed<   y)IceCandidatea*  The remote ice candidate object received from the peer connection.

    Parameters:
        candidate: The ice candidate patch SDP string (Session Description Protocol).
        sdp_mid: The SDP mid for the candidate patch.
        sdp_mline_index: The SDP mline index for the candidate patch.
    	candidatesdp_midsdp_mline_indexN)r    r!   r"   r#   r$   r%   intr   r   r   r*   r*   2   s     NLr   r*   c                   ,    e Zd ZU dZeed<   ee   ed<   y)SmallWebRTCPatchRequestzSmall WebRTC transport session arguments for the runner.

    Parameters:
        pc_id: Identifier for the peer connection.
        candidates: A list of ICE candidate patches.
    r   
candidatesN)r    r!   r"   r#   r$   r%   r	   r*   r   r   r   r0   r0   A   s     J\""r   r0   c                       e Zd ZdZdZdZy)ConnectionModez,Enum defining the connection handling modes.singlemultipleN)r    r!   r"   r#   SINGLEMULTIPLEr   r   r   r3   r3   N   s    6FHr   r3   c                       e Zd ZdZdddej
                  fdeee      de	dee
   deddf
d	Zd
ee
   ddfdZddeee      fdZdedeeged   f   deee
e
f      fdZdefdZd Zy)SmallWebRTCRequestHandlera  SmallWebRTC request handler for managing peer connections.

    This class is responsible for:
      - Handling incoming SmallWebRTC requests.
      - Creating and managing WebRTC peer connections.
      - Supporting ESP32-specific SDP munging if enabled.
      - Invoking callbacks for newly initialized connections.
      - Supporting both single and multiple connection modes.
    NFice_servers
esp32_modehostconnection_modereturnc                 J    || _         || _        || _        || _        i | _        y)a7  Initialize a SmallWebRTC request handler.

        Args:
            ice_servers (Optional[List[IceServer]]): List of ICE servers to use for WebRTC
                connections.
            esp32_mode (bool): If True, enables ESP32-specific SDP munging.
            host (Optional[str]): Host address used for SDP munging in ESP32 mode.
                Ignored if `esp32_mode` is False.
            connection_mode (ConnectionMode): Mode of operation for handling connections.
                SINGLE allows only one active connection, MULTIPLE allows several.
        N)_ice_servers_esp32_mode_host_connection_mode_pcs_map)selfr:   r;   r<   r=   s        r   __init__z"SmallWebRTCRequestHandler.__init__`   s,    $ (%
 / ;=r   r   c                    | j                   t        j                  k7  ry| j                  syt	        t        | j                  j                                     }|j                  |k7  r4|r2t        j                  d|j                   d|        t        dd      |s"t        j                  d       t        dd      y)	a  Check if the connection request satisfies single connection mode constraints.

        Args:
            pc_id: The peer connection ID from the request

        Raises:
            HTTPException: If constraints are violated in single connection mode
        Nz$Connection pc_id mismatch: existing=z, received=i  z'PC ID mismatch with existing connectionstatus_codedetailzMCannot create new connection: existing connection found but no pc_id receivedz<Cannot create new connection with existing connection active)rC   r3   r6   rD   nextitervaluesr   r   warningr   )rE   r   existing_connections      r   $_check_single_connection_constraintsz>SmallWebRTCRequestHandler._check_single_connection_constraintsz   s       N$9$99}} #4(<(<(>#?@$$-%NN67J7P7P6QQ\]b\cd  C8abbNN_  U 	 r   c                     || _         y)z;Update the list of ICE servers used for WebRTC connections.N)r@   )rE   r:   s     r   update_ice_serversz,SmallWebRTCRequestHandler.update_ice_servers   s
    'r   requestwebrtc_connection_callbackc                    K   	 |j                   } j                  |       |r j                  j                  |      nd}|rY|}t	        j
                  d|        |j                  |j                  |j                  |j                  xs d       d{    nt         j                        }|j                  |j                  |j                         d{    |j                  d      dt        f fd	       }	  ||       d{    t	        j                  d
|j                           |j#                         } j$                  rddlm}	  |	|d    j*                        |d<   | j                  |d   <   |S 7 7 7 y# t        $ r/}t	        j                   d|j                    d|        Y d}~d}~ww xY w# t        $ r6}
t	        j                   d|
        t	        j                  d|         d}
~
ww xY ww)aB  Handle a SmallWebRTC request and resolve the pending answer.

        This method will:
          - Reuse an existing WebRTC connection if `pc_id` exists.
          - Otherwise, create a new `SmallWebRTCConnection`.
          - Invoke the provided callback with the connection.
          - Manage ESP32-specific munging if enabled.
          - Enforce single/multiple connection mode constraints.

        Args:
            request (SmallWebRTCRequest): The incoming WebRTC request, containing
                SDP, type, and optionally a `pc_id`.
            webrtc_connection_callback (Callable[[Any], Awaitable[None]]): An
                asynchronous callback function that is invoked with the WebRTC connection.

        Returns:
            Dictionary containing SDP answer, type, and peer connection ID,
            or None if no answer is available.

        Raises:
            HTTPException: If connection mode constraints are violated
            Exception: Any exception raised during request handling or callback execution
                will be logged and propagated.
        Nz'Reusing existing connection for pc_id: F)r   r   r   )r:   )r   r   closedwebrtc_connectionc                    K   t        j                  d| j                          j                  j	                  | j                  d        y w)Nz&Discarding peer connection for pc_id: )r   infor   rD   r   )rW   rE   s    r   handle_disconnectedzISmallWebRTCRequestHandler.handle_web_request.<locals>.handle_disconnected   s>     KK"HIZI`I`Ha bcMM%%&7&=&=tDs   A
Az;webrtc_connection_callback executed successfully for peer: z+webrtc_connection_callback failed for peer z: r   )smallwebrtc_sdp_mungingr   r   z&Error processing SmallWebRTC request: zSmallWebRTC request details: )r   rP   rD   getr   rY   renegotiater   r   r   r   r@   
initializeevent_handlerdebug	Exceptionerror
get_answerrA   pipecat.runner.utilsr[   rB   )rE   rS   rT   r   rO   pipecat_connectionrZ   callback_erroranswerr[   es   `          r   handle_web_requestz,SmallWebRTCRequestHandler.handle_web_request   s    :2	MME 55e< ?D$--"3"3E":"%8"EeWMN(44 &11:U 5    &;tGXGX%Y"(33',,3WWW#11(;EAV E <E
45GHHHLLUVhVnVnUop (224FH 7utzz Ru-?DMM&/*ME X I ! LLEFXF^F^E__abpaqr   	LLA!EFLL8	BC	s   HBG FAG F$G F	 F&F	 4AG HG G F	 		G%F<7G <GG 	H1G>>HHc                 :  K   | j                   j                  |j                        }|st        dd      |j                  D ]R  }t        |j                        }|j                  |_        |j                  |_
        |j                  |       d{    T y7 w)z-Handle a SmallWebRTC patch candidate request.i  zPeer connection not foundrH   N)rD   r\   r   r   r1   r   r+   r,   sdpMidr-   sdpMLineIndexadd_ice_candidate)rE   rS   peer_connectioncr+   s        r   handle_patch_requestz.SmallWebRTCRequestHandler.handle_patch_request   s     --++GMM:C8STT## 	?A*1;;7I yyI&'&7&7I#!33I>>>		? ?s   BBBBc                    K   | j                   j                         D cg c]  }|j                          }}t        j                  |  d{    | j                   j                          yc c}w 7 $w)zClear the connection map.N)rD   rM   
disconnectasynciogatherclear)rE   pccoross      r   closezSmallWebRTCRequestHandler.close   sW     +/==+?+?+ABRBBnne$$$ C$s   A4A-A4A2%A4)N)r    r!   r"   r#   r3   r7   r
   r	   r   r&   r$   rF   rP   rR   r   r   r   r   r   ri   r0   rp   rx   r   r   r   r9   r9   U   s     26 "*8*A*A=d9o.= = sm	=
 (= 
=4(3- D B(htI.G (O#O %-cUIdO-C$DO 
$sCx.	!	Ob?2I ?r   r9   )r#   rs   dataclassesr   enumr   typingr   r   r   r   r	   r
   
aiortc.sdpr   fastapir   logurur   )pipecat.transports.smallwebrtc.connectionr   r   r   r*   r0   r3   r9   r   r   r   <module>r      s   
  !  A A ) !  V   2    	# 	# 	#T l lr   