gecko/dom/network/src/UDPSocketChild.cpp

211 lines
4.9 KiB
C++
Raw Normal View History

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UDPSocketChild.h"
#include "mozilla/net/NeckoChild.h"
using mozilla::net::gNeckoChild;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS1(UDPSocketChildBase, nsIUDPSocketChild)
UDPSocketChildBase::UDPSocketChildBase()
: mIPCOpen(false)
{
}
UDPSocketChildBase::~UDPSocketChildBase()
{
}
void
UDPSocketChildBase::ReleaseIPDLReference()
{
MOZ_ASSERT(mIPCOpen);
mIPCOpen = false;
this->Release();
}
void
UDPSocketChildBase::AddIPDLReference()
{
MOZ_ASSERT(!mIPCOpen);
mIPCOpen = true;
this->AddRef();
}
NS_IMETHODIMP_(nsrefcnt) UDPSocketChild::Release(void)
{
nsrefcnt refcnt = UDPSocketChildBase::Release();
if (refcnt == 1 && mIPCOpen) {
PUDPSocketChild::SendRequestDelete();
return 1;
}
return refcnt;
}
UDPSocketChild::UDPSocketChild()
:mLocalPort(0)
{
}
UDPSocketChild::~UDPSocketChild()
{
}
// nsIUDPSocketChild Methods
NS_IMETHODIMP
UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket,
const nsACString& aHost,
uint16_t aPort)
{
NS_ENSURE_ARG(aSocket);
mSocket = aSocket;
AddIPDLReference();
gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName);
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::Close()
{
SendClose();
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::Send(const nsACString& aHost,
uint16_t aPort,
const uint8_t *aData,
uint32_t aByteLength)
{
NS_ENSURE_ARG(aData);
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InfallibleTArray<uint8_t> array;
array.SwapElements(fallibleArray);
SendData(array, nsCString(aHost), aPort);
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::SendWithAddr(nsINetAddr *aAddr,
const uint8_t *aData,
uint32_t aByteLength)
{
NS_ENSURE_ARG(aAddr);
NS_ENSURE_ARG(aData);
NetAddr addr;
aAddr->GetNetAddr(&addr);
return SendWithAddress(&addr, aData, aByteLength);
}
NS_IMETHODIMP
UDPSocketChild::SendWithAddress(const NetAddr *aAddr,
const uint8_t *aData,
uint32_t aByteLength)
{
NS_ENSURE_ARG(aAddr);
NS_ENSURE_ARG(aData);
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InfallibleTArray<uint8_t> array;
array.SwapElements(fallibleArray);
SendDataWithAddress(array, *aAddr);
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::GetLocalPort(uint16_t *aLocalPort)
{
NS_ENSURE_ARG_POINTER(aLocalPort);
*aLocalPort = mLocalPort;
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress)
{
aLocalAddress = mLocalAddress;
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::SetFilterName(const nsACString &aFilterName)
{
if (!mFilterName.IsEmpty()) {
// filter name can only be set once.
return NS_ERROR_FAILURE;
}
mFilterName = aFilterName;
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::GetFilterName(nsACString &aFilterName)
{
aFilterName = mFilterName;
return NS_OK;
}
// PUDPSocketChild Methods
bool
UDPSocketChild::RecvCallback(const nsCString &aType,
const UDPCallbackData &aData,
const nsCString &aState)
{
if (NS_FAILED(mSocket->UpdateReadyState(aState)))
NS_ERROR("Shouldn't fail!");
nsresult rv = NS_ERROR_FAILURE;
if (aData.type() == UDPCallbackData::Tvoid_t) {
rv = mSocket->CallListenerVoid(aType);
} else if (aData.type() == UDPCallbackData::TUDPError) {
const UDPError& err(aData.get_UDPError());
rv = mSocket->CallListenerError(aType, err.message(), err.filename(),
err.lineNumber(), err.columnNumber());
} else if (aData.type() == UDPCallbackData::TUDPMessage) {
const UDPMessage& message(aData.get_UDPMessage());
InfallibleTArray<uint8_t> data(message.data());
rv = mSocket->CallListenerReceivedData(aType, message.fromAddr(), message.port(),
data.Elements(), data.Length());
} else if (aData.type() == UDPCallbackData::TUDPAddressInfo) {
//update local address and port.
const UDPAddressInfo& addressInfo(aData.get_UDPAddressInfo());
mLocalAddress = addressInfo.local();
mLocalPort = addressInfo.port();
rv = mSocket->CallListenerVoid(aType);
} else if (aData.type() == UDPCallbackData::TUDPSendResult) {
const UDPSendResult& returnValue(aData.get_UDPSendResult());
rv = mSocket->CallListenerSent(aType, returnValue.value());
} else {
MOZ_ASSERT("Invalid callback type!");
}
NS_ENSURE_SUCCESS(rv, true);
return true;
}
} // namespace dom
} // namespace mozilla