1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/tcp_server_socket_private_resource.h" 6 7 #include "ppapi/proxy/ppapi_messages.h" 8 #include "ppapi/proxy/tcp_socket_private_resource.h" 9 10 namespace ppapi { 11 namespace proxy { 12 13 TCPServerSocketPrivateResource::TCPServerSocketPrivateResource( 14 Connection connection, 15 PP_Instance instance) 16 : PluginResource(connection, instance), 17 state_(STATE_BEFORE_LISTENING), 18 local_addr_() { 19 SendCreate(BROWSER, PpapiHostMsg_TCPServerSocket_CreatePrivate()); 20 } 21 22 TCPServerSocketPrivateResource::~TCPServerSocketPrivateResource() { 23 } 24 25 thunk::PPB_TCPServerSocket_Private_API* 26 TCPServerSocketPrivateResource::AsPPB_TCPServerSocket_Private_API() { 27 return this; 28 } 29 30 int32_t TCPServerSocketPrivateResource::Listen( 31 const PP_NetAddress_Private* addr, 32 int32_t backlog, 33 scoped_refptr<TrackedCallback> callback) { 34 if (!addr) 35 return PP_ERROR_BADARGUMENT; 36 if (state_ != STATE_BEFORE_LISTENING) 37 return PP_ERROR_FAILED; 38 if (TrackedCallback::IsPending(listen_callback_)) 39 return PP_ERROR_INPROGRESS; 40 41 listen_callback_ = callback; 42 43 // Send the request, the browser will call us back via ListenACK 44 Call<PpapiPluginMsg_TCPServerSocket_ListenReply>( 45 BROWSER, 46 PpapiHostMsg_TCPServerSocket_Listen(*addr, backlog), 47 base::Bind(&TCPServerSocketPrivateResource::OnPluginMsgListenReply, 48 base::Unretained(this))); 49 return PP_OK_COMPLETIONPENDING; 50 } 51 52 int32_t TCPServerSocketPrivateResource::Accept( 53 PP_Resource* tcp_socket, 54 scoped_refptr<TrackedCallback> callback) { 55 if (!tcp_socket) 56 return PP_ERROR_BADARGUMENT; 57 if (state_ != STATE_LISTENING) 58 return PP_ERROR_FAILED; 59 if (TrackedCallback::IsPending(accept_callback_)) 60 return PP_ERROR_INPROGRESS; 61 62 accept_callback_ = callback; 63 64 Call<PpapiPluginMsg_TCPServerSocket_AcceptReply>( 65 BROWSER, 66 PpapiHostMsg_TCPServerSocket_Accept(), 67 base::Bind(&TCPServerSocketPrivateResource::OnPluginMsgAcceptReply, 68 base::Unretained(this), tcp_socket)); 69 return PP_OK_COMPLETIONPENDING; 70 } 71 72 int32_t TCPServerSocketPrivateResource::GetLocalAddress( 73 PP_NetAddress_Private* addr) { 74 if (!addr) 75 return PP_ERROR_BADARGUMENT; 76 if (state_ != STATE_LISTENING) 77 return PP_ERROR_FAILED; 78 *addr = local_addr_; 79 return PP_OK; 80 } 81 82 void TCPServerSocketPrivateResource::StopListening() { 83 if (state_ == STATE_CLOSED) 84 return; 85 state_ = STATE_CLOSED; 86 Post(BROWSER, PpapiHostMsg_TCPServerSocket_StopListening()); 87 if (TrackedCallback::IsPending(listen_callback_)) 88 listen_callback_->PostAbort(); 89 if (TrackedCallback::IsPending(accept_callback_)) 90 accept_callback_->PostAbort(); 91 } 92 93 void TCPServerSocketPrivateResource::OnPluginMsgListenReply( 94 const ResourceMessageReplyParams& params, 95 const PP_NetAddress_Private& local_addr) { 96 if (state_ != STATE_BEFORE_LISTENING || 97 !TrackedCallback::IsPending(listen_callback_)) { 98 return; 99 } 100 if (params.result() == PP_OK) { 101 local_addr_ = local_addr; 102 state_ = STATE_LISTENING; 103 } 104 listen_callback_->Run(params.result()); 105 } 106 107 void TCPServerSocketPrivateResource::OnPluginMsgAcceptReply( 108 PP_Resource* tcp_socket, 109 const ResourceMessageReplyParams& params, 110 int pending_resource_id, 111 const PP_NetAddress_Private& local_addr, 112 const PP_NetAddress_Private& remote_addr) { 113 DCHECK(tcp_socket); 114 if (state_ != STATE_LISTENING || 115 !TrackedCallback::IsPending(accept_callback_)) { 116 return; 117 } 118 if (params.result() == PP_OK) { 119 *tcp_socket = (new TCPSocketPrivateResource(connection(), pp_instance(), 120 pending_resource_id, 121 local_addr, 122 remote_addr))->GetReference(); 123 } 124 accept_callback_->Run(params.result()); 125 } 126 127 } // namespace proxy 128 } // namespace ppapi 129