Exemple #1
0
  def handle_ice_candidate(self, client, data):
    '''Handle ice candidate from local user.

    Args:
      client : local user
      data : ice candidate message from local user.

    Whenever the local frontend ends its ice candidate, it's expecting the ice candiate from the remote end.
    We will use a fake ice candidate for the remote end to trick the frontend to use an ice candidate that points to a port that our proxy is listening to intercept webrtc traffice.
    If the SDP for remote end has not been received yet, we postpone the reply of ice candidate because WebRTC requires SDP to be set up before receiving ice candidate message.
    '''
    candidate = Candidate.from_string(data.candidate)
    if client.media_sink_ports.get(data.socketId) is None:
      port = int(candidate.port)
      client.media_sink_ports[data.socketId] = port
      client.ctrl_seqs[port] = 0
      client.remote_cids[port] = data.socketId
      if client.media_source_port is None:
        client.media_source_port = int(candidate.port)
      if client.ip is None:
        client.ip = candidate.ip
      
      candidate = Candidate(('127.0.0.1', str(self.listen_port)))
      d = RTCData(candidate = str(candidate), socketId = data.socketId)
      msg = RTCMessage('receive_ice_candidate', d)
      remote_user = self.roster[data.socketId]
      remote_user.set_ice_candidate_msg(msg)
      # sdp answer has already been sent
      if remote_user.sdp_sent:
        self.client.sendMessage(str(msg))
Exemple #2
0
  def sdp_callback(self, interest, data):
    '''A callback function for incoming sdp description from remote users.

    Args:
      interest : PyCCN.UpcallInfo.Interest
      data : PyCCN.UpcallInfo.ContentObject

    Send the sdp to the frontend. If we already received the ICE candidate for the same remote user, then we also send out this ICE candidate.
    '''
    content = data.content
    offer_msg = RTCMessage.from_string(content)
    d = RTCData(socketId = self.client.id, sdp = offer_msg.data.sdp)
    # this is the answer to the local user
    answer_msg = RTCMessage('receive_answer', offer_msg.data)
    self.client.sendMessage(str(answer_msg))
    remote_user = self.roster[offer_msg.data.socketId]
    remote_user.set_sdp_sent()
    # we received ice candidate before sending answer
    if remote_user.ice_candidate_msg is not None:
      self.client.sendMessage(str(remote_user.ice_candidate_msg))
Exemple #3
0
  def process(self, client, msg):
    '''Process the message from the local user's front end.

    Args:
      client (PeetsServerProtocol) : local user.
      msg (RTCMessage) : the message from frontend.
    '''
    rtcMsg = RTCMessage.from_string(msg)
    handler = self.handlers.get(rtcMsg.eventName)
    if handler is not None:
      handler(client, rtcMsg.data)
    else:
      PeetsServerFactory.__logger.error("Unknown event name: " + rtcMsg.eventName)
Exemple #4
0
  def handle_join(self, client, data):
    '''Handle join message from the frontend

    Args:
      client : local user
      data : join message from local user
    '''
    PeetsServerFactory.__logger.debug('join from client %s', client.id)

    d = RTCData(connections = [])
    msg = RTCMessage('get_peers', d)
    client.sendMessage(str(msg))
    client.local_user.nick = self.nick
    client.local_user.prefix = self.prefix
Exemple #5
0
  def peets_msg_callback(self, peets_msg):
    '''A callback function to process the peets message (to be used by Roster).

    Args:
      peets_msg (PeetsMessage) : The received PeetsMessage.

    Basically, it needs to inform the status change or text chat to the front end and als fetch sdp for the new remote user if the PeetsMessage is a Join.
    '''
    remote_user = RemoteUser(peets_msg.user)
    if peets_msg.msg_type == PeetsMessage.Join or peets_msg.msg_type == PeetsMessage.Hello:
      if self.roster.has_key(remote_user.uid):
        self.__class__.__logger.debug("Redundant join message from %s", remote_user.get_sync_prefix())
        exit(0)
        return
      
      self.roster[remote_user.uid] = remote_user
      self.__class__.__logger.debug("Peets join message from remote user: %s", remote_user.get_sync_prefix())
      data = RTCData(socketId = remote_user.uid, username= remote_user.nick)
      msg = RTCMessage('new_peer_connected', data)
      self.client.sendMessage(str(msg))
      name = remote_user.get_sdp_prefix()
      
      # ask for sdp message for the new remote user
      self.ccnx_socket.send_interest(name, PeetsClosure(msg_callback = self.sdp_callback))
      

    elif peets_msg.msg_type == PeetsMessage.Leave:
      del self.roster[remote_user.uid]
      self.__class__.__logger.debug("Peets leave message from remote user: %s", remote_user.get_sync_prefix())
      data = RTCData(socketId = remote_user.uid)
      msg = RTCMessage('remove_peer_connected', data)
      self.client.sendMessage(str(msg))

    elif peets_msg.msg_type == PeetsMessage.Chat:
      data = RTCData(socketId = remote_user.uid, messages = peets_msg.extra, username = remote_user.nick)
      msg = RTCMessage('receive_chat_msg', data)
      self.client.sendMessage(str(msg))
Exemple #6
0
  def handle_offer(self, client, data):
    '''Handle the offer (sdp) from the front end

    Args:
      client : local user
      data : offer sdp message

    We store the offer for later use (we will use the same offer for all the PeerConnection this local user is going to establish) and also publish it to NDN.
    '''
    if client.media_source_sdp is None:
      client.media_source_sdp = data.sdp

    d = RTCData(sdp = client.media_source_sdp, socketId = client.id)
    msg = RTCMessage('receive_offer', d)

    name = client.local_user.get_sdp_prefix() 
    # publish sdp msg
    self.ccnx_socket.publish_content(name, str(msg))


    def publish(interest):
      self.ccnx_socket.publish_content(name, str(msg))

    self.ccnx_socket.register_prefix(name, PeetsClosure(incoming_interest_callback = publish))