SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RakNetSocket2_NativeClient.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #include "slikenet/EmptyHeader.h"
17
18 #ifdef RAKNET_SOCKET_2_INLINE_FUNCTIONS
19
20 #ifndef RAKNETSOCKET2_NATIVE_CLIENT_CPP
21 #define RAKNETSOCKET2_NATIVE_CLIENT_CPP
22
23 #if defined(__native_client__)
24
25 using namespace pp;
26
27 RNS2BindResult RNS2_NativeClient::Bind( NativeClientBindParameters *bindParameters, const char *file, unsigned int line )
28 {
29 memcpy(&binding, bindParameters, sizeof(NativeClientBindParameters));
30
31 if(Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))
32 {
33 rns2Socket = ((PPB_UDPSocket_Private_0_4*) Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->Create(bindParameters->nativeClientInstance);
34 RAKNET_DEBUG_PRINTF("CreateChromeSocket(%d,%s,0x%08x,%d) ==> 0x%08x\n", bindParameters->port, bindParameters->forceHostAddress?bindParameters->forceHostAddress:"(null)",bindParameters->nativeClientInstance,bindParameters->is_ipv6, rns2Socket);
35
36 // Enable the broadcast feature on the socket (must happen before the
37 // bind call)
38 ((PPB_UDPSocket_Private_0_4*) pp::Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->SetSocketFeature(rns2Socket, PP_UDPSOCKETFEATURE_BROADCAST, PP_MakeBool(PP_TRUE));
39
40 PP_NetAddress_Private client_addr;
41 uint8_t ipv6[16], ipv4[4];
42 if (bindParameters->forceHostAddress)
43 {
44 unsigned int ipIdx=0;
45 char * pch;
46 pch = strtok ((char*) bindParameters->forceHostAddress,".");
47 if (bindParameters->is_ipv6)
48 {
49 while (pch != NULL && ipIdx<16)
50 {
51 ipv6[ipIdx++]=atoi(pch);
52 pch = strtok (NULL, ".");
53 }
54 NetAddressPrivate::CreateFromIPv6Address(ipv6,0,bindParameters->port,&client_addr);
55 }
56 else
57 {
58 while (pch != NULL && ipIdx<4)
59 {
60 ipv4[ipIdx++]=atoi(pch);
61 pch = strtok (NULL, ".");
62 }
63 NetAddressPrivate::CreateFromIPv4Address(ipv4,bindParameters->port,&client_addr);
64 }
65 }
66 else
67 {
68 NetAddressPrivate::GetAnyAddress(bindParameters->is_ipv6, &client_addr);
69 NetAddressPrivate::ReplacePort(client_addr, bindParameters->port, &client_addr);
70 }
71
72 bindState = BS_IN_PROGRESS;
73
74 RAKNET_DEBUG_PRINTF("attempting to bind to %s\n", NetAddressPrivate::Describe(client_addr, true).c_str());
75 PP_CompletionCallback cc = PP_MakeCompletionCallback(RNS2_NativeClient::onSocketBound, this);
76 ((PPB_UDPSocket_Private_0_4*) Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->Bind(rns2Socket, &client_addr, cc);
77 return BR_SUCCESS;
78 }
79 return BR_FAILED_TO_BIND_SOCKET;
80 }
81
82 void RNS2_NativeClient::SendImmediate(RNS2_SendParameters_NativeClient *sp)
83 {
84 // Assuming data does not have to remain valid until callback called
85 PP_NetAddress_Private client_addr;
86 #if RAKNET_SUPPORT_IPV6==1
87 NetAddressPrivate::CreateFromIPv6Address(sp->systemAddress.address.addr6.sin6_addr.u.Byte,0,sp->systemAddress.GetPort(),&client_addr);
88 #else
89 NetAddressPrivate::CreateFromIPv4Address((const uint8_t*) &sp->systemAddress.address.addr4.sin_addr,sp->systemAddress.GetPort(),&client_addr);
90 #endif
91
92 // sp remains in memory until the callback completes
93 PP_CompletionCallback cc = PP_MakeCompletionCallback(onSendTo, sp);
94 ((PPB_UDPSocket_Private_0_4*) Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->SendTo(sp->socket2->rns2Socket, sp->data, sp->length, &client_addr, cc);
95 }
96
97 void RNS2_NativeClient::onRecvFrom(void* pData, int32_t dataSize)
98 {
99 RNS2RecvStruct *recvStruct = (RNS2RecvStruct *) pData;
100 RNS2_NativeClient *socket2 = (RNS2_NativeClient *) recvStruct->socket;
101
102 //any error codes will be given to us in the dataSize value; see pp_errors.h for a list of errors
103 if(dataSize <=0 || !pData )
104 {
105 // Free data
106 socket2->eventHandler->DeallocRNS2RecvStruct(recvStruct, _FILE_AND_LINE_);
107
108 // This value indicates failure due to an asynchronous operation being
109 // interrupted. The most common cause of this error code is destroying
110 // a resource that still has a callback pending. All callbacks are
111 // guaranteed to execute, so any callbacks pending on a destroyed
112 // resource will be issued with PP_ERROR_ABORTED.
113 if(dataSize==PP_ERROR_ABORTED)
114 {
115 RAKNET_DEBUG_PRINTF("onRecvFrom error PP_ERROR_ABORTED, killing recvfrom loop\n");
116 }
117 else
118 {
119 RAKNET_DEBUG_PRINTF("onRecvFrom error %d\n", dataSize);
120
121 // Reissue call
122 socket2->IssueReceiveCall();
123 }
124
125 return;
126 }
127
128 recvStruct->bytesRead=dataSize;
129 recvStruct->timeRead= SLNet::GetTimeUS();
130
131
132 PP_NetAddress_Private addr;
133 bool ok=false;
134 if(((PPB_UDPSocket_Private_0_4*) Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->GetRecvFromAddress(socket2->rns2Socket, &addr) == PP_TRUE)
135 {
136 PP_NetAddressFamily_Private family = NetAddressPrivate::GetFamily(addr);
137 if (family == PP_NETADDRESSFAMILY_IPV4)
138 {
139 ok = NetAddressPrivate::GetAddress(addr, &recvStruct->systemAddress.address.addr4.sin_addr, sizeof(in_addr));
140 }
141 #if RAKNET_SUPPORT_IPV6==1
142 else
143 {
144 ok = NetAddressPrivate::GetAddress(addr, &recvStruct->systemAddress.address.addr6.sin6_addr, sizeof(in6_addr));
145 }
146 #endif
147 }
148
149 if(ok)
150 {
151 recvStruct->systemAddress.SetPortHostOrder(pp::NetAddressPrivate::GetPort(addr));
152 socket2->binding.eventHandler->OnRNS2Recv(recvStruct);
153 }
154
155 // Reissue call
156 socket2->IssueReceiveCall();
157 }
158 void RNS2_NativeClient::IssueReceiveCall(void)
159 {
160 RNS2RecvStruct *recvFromStruct;
161 recvFromStruct=binding.eventHandler->AllocRNS2RecvStruct(_FILE_AND_LINE_);
162 if (recvFromStruct != NULL)
163 {
164 recvFromStruct->socket=this;
165 PP_CompletionCallback cc = PP_MakeCompletionCallback(onRecvFrom, recvFromStruct);
166 ((PPB_UDPSocket_Private_0_4*) Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4))->RecvFrom(rns2Socket, recvFromStruct->data, MAXIMUM_MTU_SIZE, cc);
167 }
168 }
169
170 #endif // defined(__native_client__)
171
172 #endif // file header
173
174 #endif // #ifdef RAKNET_SOCKET_2_INLINE_FUNCTIONS