Merge branch 'master' of https://github.com/cocos2d/cocos2d-x into bind_cocosbuilder

This commit is contained in:
samuele3hu 2013-06-03 13:48:12 +08:00
commit af0737ce87
364 changed files with 8462 additions and 5089 deletions

View File

@ -26,6 +26,8 @@ THE SOFTWARE.
#ifndef __MINGW32__
NS_CC_BEGIN
int gettimeofday(struct timeval * val, struct timezone *)
{
if (val)
@ -39,4 +41,6 @@ int gettimeofday(struct timeval * val, struct timezone *)
return 0;
}
NS_CC_END
#endif // __MINGW32__

View File

@ -87,6 +87,7 @@ THE SOFTWARE.
#include <WinSock2.h>
NS_CC_BEGIN
struct timezone
{
@ -96,6 +97,8 @@ struct timezone
int CC_DLL gettimeofday(struct timeval *, struct timezone *);
NS_CC_END
#else
#include <winsock.h>

View File

@ -49,6 +49,7 @@ GUI/CCScrollView/CCSorting.cpp \
GUI/CCEditBox/CCEditBox.cpp \
GUI/CCEditBox/CCEditBoxImplAndroid.cpp \
network/HttpClient.cpp \
network/WebSocket.cpp \
physics_nodes/CCPhysicsDebugNode.cpp \
physics_nodes/CCPhysicsSprite.cpp \
LocalStorage/LocalStorageAndroid.cpp \
@ -77,6 +78,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_curl_static
LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static
LOCAL_WHOLE_STATIC_LIBRARIES += libwebsockets_static
LOCAL_CFLAGS += -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
LOCAL_EXPORT_CFLAGS += -DCC_ENABLE_CHIPMUNK_INTEGRATION=1
@ -95,3 +97,4 @@ $(call import-module,CocosDenshion/android)
$(call import-module,cocos2dx/platform/third_party/android/prebuilt/libcurl)
$(call import-module,external/Box2D)
$(call import-module,external/chipmunk)
$(call import-module,external/libwebsockets/android)

View File

@ -0,0 +1,659 @@
/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
Copyright (c) 2013 James Chen
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "WebSocket.h"
#include <queue>
#include <signal.h>
#include <errno.h>
NS_CC_EXT_BEGIN
class WsMessage
{
public:
WsMessage() : what(0), obj(NULL){}
unsigned int what; // message type
void* obj;
};
/**
* @brief Websocket thread helper, it's used for sending message between UI thread and websocket thread.
*/
class WsThreadHelper : public cocos2d::CCObject
{
public:
WsThreadHelper();
~WsThreadHelper();
// Creates a new thread
bool createThread(const WebSocket& ws);
// Quits sub-thread (websocket thread).
void quitSubThread();
// Schedule callback function
virtual void update(float dt);
// Sends message to UI thread. It's needed to be invoked in sub-thread.
void sendMessageToUIThread(WsMessage *msg);
// Sends message to sub-thread(websocket thread). It's needs to be invoked in UI thread.
void sendMessageToSubThread(WsMessage *msg);
// Waits the sub-thread (websocket thread) to exit,
void joinSubThread();
protected:
friend class WsThreadEntry;
void* wsThreadEntryFunc(void* arg);
private:
std::list<WsMessage*>* _UIWsMessageQueue;
std::list<WsMessage*>* _subThreadWsMessageQueue;
pthread_mutex_t _UIWsMessageQueueMutex;
pthread_mutex_t _subThreadWsMessageQueueMutex;
pthread_t _subThreadInstance;
WebSocket* _ws;
bool _needQuit;
friend class WebSocket;
};
// Wrapper for converting websocket callback from static function to member function of WebSocket class.
class WebSocketCallbackWrapper {
public:
static int onSocketCallback(struct libwebsocket_context *ctx,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
{
// Gets the user data from context. We know that it's a 'WebSocket' instance.
WebSocket* wsInstance = (WebSocket*)libwebsocket_context_user(ctx);
if (wsInstance)
{
return wsInstance->onSocketCallback(ctx, wsi, reason, user, in, len);
}
return 0;
}
};
// Implementation of WsThreadHelper
WsThreadHelper::WsThreadHelper()
: _ws(NULL)
, _needQuit(false)
{
_UIWsMessageQueue = new std::list<WsMessage*>();
pthread_mutex_init(&_UIWsMessageQueueMutex, NULL);
_subThreadWsMessageQueue = new std::list<WsMessage*>();
pthread_mutex_init(&_subThreadWsMessageQueueMutex, NULL);
CCDirector::sharedDirector()->getScheduler()->scheduleUpdateForTarget(this, 0, false);
}
WsThreadHelper::~WsThreadHelper()
{
CCDirector::sharedDirector()->getScheduler()->unscheduleAllForTarget(this);
pthread_mutex_destroy(&_UIWsMessageQueueMutex);
pthread_mutex_destroy(&_subThreadWsMessageQueueMutex);
delete _UIWsMessageQueue;
delete _subThreadWsMessageQueue;
}
// For converting static function to member function
class WsThreadEntry
{
public:
static void* entry(void* arg)
{
WsThreadHelper* self = static_cast<WsThreadHelper*>(arg);
return self->wsThreadEntryFunc(arg);
}
};
bool WsThreadHelper::createThread(const WebSocket& ws)
{
_ws = const_cast<WebSocket*>(&ws);
pthread_attr_t attr;
pthread_attr_init (&attr);
// pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
// Creates websocket thread
if (0 == pthread_create(&_subThreadInstance, &attr, WsThreadEntry::entry, this))
{
return true;
}
return false;
}
void WsThreadHelper::quitSubThread()
{
_needQuit = true;
}
void* WsThreadHelper::wsThreadEntryFunc(void* arg)
{
_ws->onSubThreadStarted();
while (!_needQuit)
{
if (_ws->onSubThreadLoop())
{
break;
}
}
_ws->onSubThreadEnded();
return (void*)0;
}
void WsThreadHelper::sendMessageToUIThread(WsMessage *msg)
{
pthread_mutex_lock(&_UIWsMessageQueueMutex);
_UIWsMessageQueue->push_back(msg);
pthread_mutex_unlock(&_UIWsMessageQueueMutex);
}
void WsThreadHelper::sendMessageToSubThread(WsMessage *msg)
{
pthread_mutex_lock(&_subThreadWsMessageQueueMutex);
_subThreadWsMessageQueue->push_back(msg);
pthread_mutex_unlock(&_subThreadWsMessageQueueMutex);
}
void WsThreadHelper::joinSubThread()
{
void* ret = NULL;
pthread_join(_subThreadInstance, &ret);
}
void WsThreadHelper::update(float dt)
{
WsMessage *msg = NULL;
// Returns quickly if no message
pthread_mutex_lock(&_UIWsMessageQueueMutex);
if (0 == _UIWsMessageQueue->size())
{
pthread_mutex_unlock(&_UIWsMessageQueueMutex);
return;
}
// Gets message
msg = *(_UIWsMessageQueue->begin());
_UIWsMessageQueue->pop_front();
pthread_mutex_unlock(&_UIWsMessageQueueMutex);
if (_ws)
{
_ws->onUIThreadReceiveMessage(msg);
}
CC_SAFE_DELETE(msg);
}
enum WS_MSG {
WS_MSG_TO_SUBTRHEAD_SENDING_STRING = 0,
WS_MSG_TO_SUBTRHEAD_SENDING_BINARY,
WS_MSG_TO_SUBTRHEAD_CLOSING,
WS_MSG_TO_UITHREAD_OPEN,
WS_MSG_TO_UITHREAD_MESSAGE,
WS_MSG_TO_UITHREAD_ERROR,
WS_MSG_TO_UITHREAD_CLOSE
};
WebSocket::WebSocket()
: _readyState(kStateConnecting)
, _port(80)
, _wsHelper(NULL)
, _wsInstance(NULL)
, _wsContext(NULL)
, _delegate(NULL)
, _SSLConnection(0)
, _wsProtocols(NULL)
{
}
WebSocket::~WebSocket()
{
close();
CC_SAFE_RELEASE_NULL(_wsHelper);
for (int i = 0; _wsProtocols[i].callback != NULL; ++i) {
CC_SAFE_DELETE_ARRAY(_wsProtocols[i].name);
}
CC_SAFE_DELETE_ARRAY(_wsProtocols);
}
bool WebSocket::init(const Delegate& delegate,
const std::string& url,
const std::vector<std::string>* protocols/* = NULL*/)
{
bool ret = false;
bool useSSL = false;
std::string host = url;
int pos = 0;
int port = 80;
_delegate = const_cast<Delegate*>(&delegate);
//ws://
pos = host.find("ws://");
if (pos == 0){
host.erase(0,5);
}
pos = host.find("wss://");
if (pos == 0)
{
host.erase(0,6);
useSSL = true;
}
pos = host.find(":");
if(pos >= 0){
port = atoi(host.substr(pos+1, host.size()).c_str());
}
pos = host.find("/", pos);
std::string path = "/";
if(pos >= 0){
path += host.substr(pos + 1, host.size());
}
pos = host.find(":");
if(pos >= 0){
host.erase(pos, host.size());
}
_host = host;
_port = port;
_path = path;
_SSLConnection = useSSL ? 1 : 0;
int protocolCount = 0;
if (protocols && protocols->size() > 0)
{
protocolCount = protocols->size();
}
else
{
protocolCount = 1;
}
_wsProtocols = new libwebsocket_protocols[protocolCount+1];
memset(_wsProtocols, 0, sizeof(libwebsocket_protocols)*(protocolCount+1));
if (protocols)
{
int i = 0;
for (std::vector<std::string>::const_iterator iter = protocols->begin(); iter != protocols->end(); ++iter, ++i) {
char* name = new char[(*iter).length()+1];
strcpy(name, (*iter).c_str());
_wsProtocols[i].name = name;
_wsProtocols[i].callback = WebSocketCallbackWrapper::onSocketCallback;
}
}
else
{
char* name = new char[20];
strcpy(name, "default-protocol");
_wsProtocols[0].name = name;
_wsProtocols[0].callback = WebSocketCallbackWrapper::onSocketCallback;
}
// WebSocket thread needs to be invoked at the end of this method.
_wsHelper = new WsThreadHelper();
ret = _wsHelper->createThread(*this);
return ret;
}
void WebSocket::send(const std::string& message)
{
if (_readyState == kStateOpen)
{
// In main thread
WsMessage* msg = new WsMessage();
msg->what = WS_MSG_TO_SUBTRHEAD_SENDING_STRING;
Data* data = new Data();
data->bytes = new char[message.length()+1];
strcpy(data->bytes, message.c_str());
data->len = message.length();
msg->obj = data;
_wsHelper->sendMessageToSubThread(msg);
}
}
void WebSocket::send(const unsigned char* binaryMsg, unsigned int len)
{
CCAssert(binaryMsg != NULL && len > 0, "parameter invalid.");
if (_readyState == kStateOpen)
{
// In main thread
WsMessage* msg = new WsMessage();
msg->what = WS_MSG_TO_SUBTRHEAD_SENDING_BINARY;
Data* data = new Data();
data->bytes = new char[len];
memcpy((void*)data->bytes, (void*)binaryMsg, len);
data->len = len;
msg->obj = data;
_wsHelper->sendMessageToSubThread(msg);
}
}
void WebSocket::close()
{
CCDirector::sharedDirector()->getScheduler()->unscheduleAllForTarget(_wsHelper);
if (_readyState == kStateClosing || _readyState == kStateClosed)
return;
CCLOG("websocket (%p) connection closed by client", this);
_readyState = kStateClosed;
WsMessage* msg = new WsMessage();
msg->what = WS_MSG_TO_SUBTRHEAD_CLOSING;
_wsHelper->sendMessageToSubThread(msg);
_wsHelper->joinSubThread();
// onClose callback needs to be invoked at the end of this method
// since websocket instance may be deleted in 'onClose'.
_delegate->onClose(this);
}
WebSocket::State WebSocket::getReadyState()
{
return _readyState;
}
int WebSocket::onSubThreadLoop()
{
if (_readyState == kStateClosed || _readyState == kStateClosing)
{
libwebsocket_context_destroy(_wsContext);
// return 1 to exit the loop.
return 1;
}
if (_wsContext && _readyState != kStateClosed && _readyState != kStateClosing)
{
libwebsocket_service(_wsContext, 0);
}
// Sleep 50 ms
#ifdef WIN32
Sleep(50);
#else
usleep(50000);
#endif
// return 0 to continue the loop.
return 0;
}
void WebSocket::onSubThreadStarted()
{
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
/*
* create the websocket context. This tracks open connections and
* knows how to route any traffic and which protocol version to use,
* and if each connection is client or server side.
*
* For this client-only demo, we tell it to not listen on any port.
*/
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = _wsProtocols;
#ifndef LWS_NO_EXTENSIONS
info.extensions = libwebsocket_get_internal_extensions();
#endif
info.gid = -1;
info.uid = -1;
info.user = (void*)this;
_wsContext = libwebsocket_create_context(&info);
if(NULL != _wsContext){
_readyState = kStateConnecting;
std::string name;
for (int i = 0; _wsProtocols[i].callback != NULL; ++i) {
name += (_wsProtocols[i].name);
if (_wsProtocols[i+1].callback != NULL)
{
name += ", ";
}
}
_wsInstance = libwebsocket_client_connect(_wsContext, _host.c_str(), _port, _SSLConnection,
_path.c_str(), _host.c_str(), _host.c_str(),
name.c_str(), -1);
}
}
void WebSocket::onSubThreadEnded()
{
}
int WebSocket::onSocketCallback(struct libwebsocket_context *ctx,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
{
//CCLOG("socket callback for %d reason", reason);
CCAssert(_wsContext == NULL || ctx == _wsContext, "Invalid context.");
CCAssert(_wsInstance == NULL || wsi == NULL || wsi == _wsInstance, "Invaild websocket instance.");
switch (reason)
{
case LWS_CALLBACK_DEL_POLL_FD:
case LWS_CALLBACK_PROTOCOL_DESTROY:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
{
WsMessage* msg = new WsMessage();
if (reason == LWS_CALLBACK_CLIENT_CONNECTION_ERROR
|| (reason == LWS_CALLBACK_PROTOCOL_DESTROY && _readyState == kStateConnecting)
|| (reason == LWS_CALLBACK_DEL_POLL_FD && _readyState == kStateConnecting)
)
{
msg->what = WS_MSG_TO_UITHREAD_ERROR;
_readyState = kStateClosing;
}
else if (reason == LWS_CALLBACK_PROTOCOL_DESTROY && _readyState == kStateClosing)
{
msg->what = WS_MSG_TO_UITHREAD_CLOSE;
}
_wsHelper->sendMessageToUIThread(msg);
}
break;
case LWS_CALLBACK_CLIENT_ESTABLISHED:
{
WsMessage* msg = new WsMessage();
msg->what = WS_MSG_TO_UITHREAD_OPEN;
_readyState = kStateOpen;
/*
* start the ball rolling,
* LWS_CALLBACK_CLIENT_WRITEABLE will come next service
*/
libwebsocket_callback_on_writable(ctx, wsi);
_wsHelper->sendMessageToUIThread(msg);
}
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
{
pthread_mutex_lock(&_wsHelper->_subThreadWsMessageQueueMutex);
std::list<WsMessage*>::iterator iter = _wsHelper->_subThreadWsMessageQueue->begin();
int bytesWrite = 0;
for (; iter != _wsHelper->_subThreadWsMessageQueue->end(); ++iter) {
WsMessage* subThreadMsg = *iter;
if ( WS_MSG_TO_SUBTRHEAD_SENDING_STRING == subThreadMsg->what
|| WS_MSG_TO_SUBTRHEAD_SENDING_BINARY == subThreadMsg->what)
{
Data* data = (Data*)subThreadMsg->obj;
unsigned char* buf = new unsigned char[LWS_SEND_BUFFER_PRE_PADDING
+ data->len + LWS_SEND_BUFFER_POST_PADDING];
memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, data->len);
memcpy((char*)&buf[LWS_SEND_BUFFER_PRE_PADDING], data->bytes, data->len);
enum libwebsocket_write_protocol writeProtocol;
if (WS_MSG_TO_SUBTRHEAD_SENDING_STRING == subThreadMsg->what)
{
writeProtocol = LWS_WRITE_TEXT;
}
else
{
writeProtocol = LWS_WRITE_BINARY;
}
bytesWrite = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], data->len, writeProtocol);
if (bytesWrite < 0) {
CCLOGERROR("%s", "libwebsocket_write error...");
}
if (bytesWrite < data->len) {
CCLOGERROR("Partial write LWS_CALLBACK_CLIENT_WRITEABLE\n");
}
CC_SAFE_DELETE_ARRAY(data->bytes);
CC_SAFE_DELETE(data);
CC_SAFE_DELETE_ARRAY(buf);
}
}
_wsHelper->_subThreadWsMessageQueue->clear();
pthread_mutex_unlock(&_wsHelper->_subThreadWsMessageQueueMutex);
/* get notified as soon as we can write again */
libwebsocket_callback_on_writable(ctx, wsi);
}
break;
case LWS_CALLBACK_CLOSED:
{
CCLOG("%s", "connection closing..");
_wsHelper->quitSubThread();
if (_readyState != kStateClosed)
{
WsMessage* msg = new WsMessage();
_readyState = kStateClosed;
msg->what = WS_MSG_TO_UITHREAD_CLOSE;
_wsHelper->sendMessageToUIThread(msg);
}
}
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
{
if (in && len > 0)
{
WsMessage* msg = new WsMessage();
msg->what = WS_MSG_TO_UITHREAD_MESSAGE;
char* bytes = NULL;
Data* data = new Data();
if (lws_frame_is_binary(wsi))
{
bytes = new char[len];
data->isBinary = true;
}
else
{
bytes = new char[len+1];
bytes[len] = '\0';
data->isBinary = false;
}
memcpy(bytes, in, len);
data->bytes = bytes;
data->len = len;
msg->obj = (void*)data;
_wsHelper->sendMessageToUIThread(msg);
}
}
break;
default:
break;
}
return 0;
}
void WebSocket::onUIThreadReceiveMessage(WsMessage* msg)
{
switch (msg->what) {
case WS_MSG_TO_UITHREAD_OPEN:
{
_delegate->onOpen(this);
}
break;
case WS_MSG_TO_UITHREAD_MESSAGE:
{
Data* data = (Data*)msg->obj;
_delegate->onMessage(this, *data);
CC_SAFE_DELETE_ARRAY(data->bytes);
CC_SAFE_DELETE(data);
}
break;
case WS_MSG_TO_UITHREAD_CLOSE:
{
_delegate->onClose(this);
}
break;
case WS_MSG_TO_UITHREAD_ERROR:
{
// FIXME: The exact error needs to be checked.
WebSocket::ErrorCode err = kErrorConnectionFailure;
_delegate->onError(this, err);
}
break;
default:
break;
}
}
NS_CC_EXT_END

View File

@ -0,0 +1,154 @@
/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
Copyright (c) 2013 James Chen
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_WEBSOCKET_H__
#define __CC_WEBSOCKET_H__
#include "ExtensionMacros.h"
#include <pthread.h>
#include "cocos2d.h"
#include "libwebsockets.h"
#include <list>
NS_CC_EXT_BEGIN
class WsThreadHelper;
class WsMessage;
class WebSocket
{
public:
WebSocket();
virtual ~WebSocket();
/**
* @brief Data structure for message
*/
struct Data
{
Data():bytes(NULL), len(0), isBinary(false){}
char* bytes;
int len;
bool isBinary;
};
/**
* @brief Errors in websocket
*/
enum ErrorCode
{
kErrorTimeout = 0,
kErrorConnectionFailure,
kErrorUnknown
};
/**
* @brief The delegate class to process websocket events.
*/
class Delegate
{
public:
virtual ~Delegate() {}
virtual void onOpen(WebSocket* ws) = 0;
virtual void onMessage(WebSocket* ws, const Data& data) = 0;
virtual void onClose(WebSocket* ws) = 0;
virtual void onError(WebSocket* ws, const ErrorCode& error) = 0;
};
/**
* @brief The initialized method for websocket.
* It needs to be invoked right after websocket instance is allocated.
* @param delegate The delegate which want to receive event from websocket.
* @param url The URL of websocket server.
* @return true: Success, false: Failure
*/
bool init(const Delegate& delegate,
const std::string& url,
const std::vector<std::string>* protocols = NULL);
/**
* @brief Sends string data to websocket server.
*/
void send(const std::string& message);
/**
* @brief Sends binary data to websocket server.
*/
void send(const unsigned char* binaryMsg, unsigned int len);
/**
* @brief Closes the connection to server.
*/
void close();
/**
* Websocket state
*/
enum State
{
kStateConnecting = 0,
kStateOpen,
kStateClosing,
kStateClosed
};
/**
* @brief Gets current state of connection.
*/
State getReadyState();
private:
virtual void onSubThreadStarted();
virtual int onSubThreadLoop();
virtual void onSubThreadEnded();
virtual void onUIThreadReceiveMessage(WsMessage* msg);
friend class WebSocketCallbackWrapper;
int onSocketCallback(struct libwebsocket_context *ctx,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len);
private:
State _readyState;
std::string _host;
unsigned int _port;
std::string _path;
friend class WsThreadHelper;
WsThreadHelper* _wsHelper;
struct libwebsocket* _wsInstance;
struct libwebsocket_context* _wsContext;
Delegate* _delegate;
int _SSLConnection;
libwebsocket_protocols* _wsProtocols;
};
NS_CC_EXT_END
#endif /* defined(__CC_JSB_WEBSOCKET_H__) */

View File

@ -63,7 +63,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\zlib;$(ProjectDir)..\..\CocosDenshion\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\external\libwebsockets\win32\include;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\zlib;$(ProjectDir)..\..\CocosDenshion\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_LIB;COCOS2D_DEBUG=1;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -79,7 +79,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\zlib;$(ProjectDir)..\..\CocosDenshion\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(ProjectDir)..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\external\sqlite3\include;$(ProjectDir)..\..\external;$(ProjectDir)..\..\external\libwebsockets\win32\include;$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\zlib;$(ProjectDir)..\..\CocosDenshion\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_LIB;CC_ENABLE_CHIPMUNK_INTEGRATION=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -136,6 +136,7 @@
<ClCompile Include="..\GUI\CCScrollView\CCTableViewCell.cpp" />
<ClCompile Include="..\LocalStorage\LocalStorage.cpp" />
<ClCompile Include="..\network\HttpClient.cpp" />
<ClCompile Include="..\network\Websocket.cpp" />
<ClCompile Include="..\physics_nodes\CCPhysicsDebugNode.cpp" />
<ClCompile Include="..\physics_nodes\CCPhysicsSprite.cpp" />
<ClCompile Include="..\spine\Animation.cpp" />
@ -215,6 +216,7 @@
<ClInclude Include="..\network\HttpClient.h" />
<ClInclude Include="..\network\HttpRequest.h" />
<ClInclude Include="..\network\HttpResponse.h" />
<ClInclude Include="..\network\Websocket.h" />
<ClInclude Include="..\physics_nodes\CCPhysicsDebugNode.h" />
<ClInclude Include="..\physics_nodes\CCPhysicsSprite.h" />
<ClInclude Include="..\spine\Animation.h" />

View File

@ -13,9 +13,6 @@
<Filter Include="GUI\CCScrollView">
<UniqueIdentifier>{46797895-f71d-4ddb-b381-d0884e678d39}</UniqueIdentifier>
</Filter>
<Filter Include="GUI\network">
<UniqueIdentifier>{2a7741ff-87a5-41c8-8e51-d7a1cf0c8e4d}</UniqueIdentifier>
</Filter>
<Filter Include="physics_nodes">
<UniqueIdentifier>{d5806151-7ae1-4fef-af5a-2fa1d1c7377b}</UniqueIdentifier>
</Filter>
@ -31,13 +28,16 @@
<Filter Include="spine">
<UniqueIdentifier>{ff4b5934-99d4-4ea7-9f50-a774192d9ca9}</UniqueIdentifier>
</Filter>
<Filter Include="network">
<UniqueIdentifier>{2a7741ff-87a5-41c8-8e51-d7a1cf0c8e4d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\GUI\CCScrollView\CCScrollView.cpp">
<Filter>GUI\CCScrollView</Filter>
</ClCompile>
<ClCompile Include="..\network\HttpClient.cpp">
<Filter>GUI\network</Filter>
<Filter>network</Filter>
</ClCompile>
<ClCompile Include="..\GUI\CCScrollView\CCSorting.cpp">
<Filter>GUI\CCScrollView</Filter>
@ -234,6 +234,9 @@
<ClCompile Include="..\spine\spine-cocos2dx.cpp">
<Filter>spine</Filter>
</ClCompile>
<ClCompile Include="..\network\Websocket.cpp">
<Filter>network</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\GUI\CCScrollView\CCScrollView.h">
@ -242,13 +245,13 @@
<ClInclude Include="..\cocos-ext.h" />
<ClInclude Include="..\ExtensionMacros.h" />
<ClInclude Include="..\network\HttpClient.h">
<Filter>GUI\network</Filter>
<Filter>network</Filter>
</ClInclude>
<ClInclude Include="..\network\HttpRequest.h">
<Filter>GUI\network</Filter>
<Filter>network</Filter>
</ClInclude>
<ClInclude Include="..\network\HttpResponse.h">
<Filter>GUI\network</Filter>
<Filter>network</Filter>
</ClInclude>
<ClInclude Include="..\GUI\CCScrollView\CCSorting.h">
<Filter>GUI\CCScrollView</Filter>
@ -466,5 +469,8 @@
<ClInclude Include="..\spine\spine.h">
<Filter>spine</Filter>
</ClInclude>
<ClInclude Include="..\network\Websocket.h">
<Filter>network</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libwebsockets_static
LOCAL_MODULE_FILENAME := libwebsockets_static
LOCAL_SRC_FILES := ./lib/$(TARGET_ARCH_ABI)/libwebsockets.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CPPFLAGS := -D__STDC_LIMIT_MACROS=1
LOCAL_EXPORT_CPPFLAGS := -D__STDC_LIMIT_MACROS=1
include $(PREBUILT_STATIC_LIBRARY)

View File

@ -0,0 +1,993 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef __LIBWEBSOCKET_H__
#define __LIBWEBSOCKET_H__
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include "../win32port/win32helpers/websock-w32.h"
#include "../win32port/win32helpers/gettimeofday.h"
#define strcasecmp stricmp
#define getdtablesize() 30000
typedef int ssize_t;
#define LWS_VISIBLE
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#else
#define LWS_EXTERN extern __declspec(dllimport)
#endif
#else
#define LWS_EXTERN
#endif
#else // NOT WIN32
#include <poll.h>
#include <unistd.h>
#if defined(__GNUC__)
#define LWS_VISIBLE __attribute__((visibility("default")))
#else
#define LWS_VISIBLE
#endif
#endif
#include <assert.h>
#ifndef LWS_EXTERN
#define LWS_EXTERN extern
#endif
#define CONTEXT_PORT_NO_LISTEN 0
#define MAX_MUX_RECURSION 2
enum lws_log_levels {
LLL_ERR = 1 << 0,
LLL_WARN = 1 << 1,
LLL_NOTICE = 1 << 2,
LLL_INFO = 1 << 3,
LLL_DEBUG = 1 << 4,
LLL_PARSER = 1 << 5,
LLL_HEADER = 1 << 6,
LLL_EXT = 1 << 7,
LLL_CLIENT = 1 << 8,
LLL_LATENCY = 1 << 9,
LLL_COUNT = 10 /* set to count of valid flags */
};
LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...);
/* notice, warn and log are always compiled in */
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__)
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__)
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
/*
* weaker logging can be deselected at configure time using --disable-debug
* that gets rid of the overhead of checking while keeping _warn and _err
* active
*/
#ifdef _DEBUG
#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__)
#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__)
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__)
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__)
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__)
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__)
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__)
LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len);
#else /* no debug */
#define lwsl_info(...)
#define lwsl_debug(...)
#define lwsl_parser(...)
#define lwsl_header(...)
#define lwsl_ext(...)
#define lwsl_client(...)
#define lwsl_latency(...)
#define lwsl_hexdump(a, b)
#endif
enum libwebsocket_context_options {
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
};
enum libwebsocket_callback_reasons {
LWS_CALLBACK_ESTABLISHED,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
LWS_CALLBACK_CLIENT_ESTABLISHED,
LWS_CALLBACK_CLOSED,
LWS_CALLBACK_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_SERVER_WRITEABLE,
LWS_CALLBACK_HTTP,
LWS_CALLBACK_HTTP_FILE_COMPLETION,
LWS_CALLBACK_HTTP_WRITEABLE,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
LWS_CALLBACK_PROTOCOL_INIT,
LWS_CALLBACK_PROTOCOL_DESTROY,
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD,
LWS_CALLBACK_DEL_POLL_FD,
LWS_CALLBACK_SET_MODE_POLL_FD,
LWS_CALLBACK_CLEAR_MODE_POLL_FD,
};
#ifndef LWS_NO_EXTENSIONS
enum libwebsocket_extension_callback_reasons {
LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE,
LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
LWS_EXT_CALLBACK_DESTROY,
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING,
LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
LWS_EXT_CALLBACK_1HZ,
LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
LWS_EXT_CALLBACK_IS_WRITEABLE,
LWS_EXT_CALLBACK_PAYLOAD_TX,
LWS_EXT_CALLBACK_PAYLOAD_RX,
};
#endif
enum libwebsocket_write_protocol {
LWS_WRITE_TEXT,
LWS_WRITE_BINARY,
LWS_WRITE_CONTINUATION,
LWS_WRITE_HTTP,
/* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,
LWS_WRITE_PONG,
/* flags */
LWS_WRITE_NO_FIN = 0x40,
/*
* client packet payload goes out on wire unmunged
* only useful for security tests since normal servers cannot
* decode the content if used
*/
LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
};
/*
* you need these to look at headers that have been parsed if using the
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum
* list below is absent, .token = NULL and token_len = 0. Otherwise .token
* points to .token_len chars containing that header content.
*/
struct lws_tokens {
char *token;
int token_len;
};
enum lws_token_indexes {
WSI_TOKEN_GET_URI,
WSI_TOKEN_HOST,
WSI_TOKEN_CONNECTION,
WSI_TOKEN_KEY1,
WSI_TOKEN_KEY2,
WSI_TOKEN_PROTOCOL,
WSI_TOKEN_UPGRADE,
WSI_TOKEN_ORIGIN,
WSI_TOKEN_DRAFT,
WSI_TOKEN_CHALLENGE,
/* new for 04 */
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
/* new for 05 */
WSI_TOKEN_EXTENSIONS,
/* client receives these */
WSI_TOKEN_ACCEPT,
WSI_TOKEN_NONCE,
WSI_TOKEN_HTTP,
WSI_TOKEN_MUXURL,
/* use token storage to stash these */
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
_WSI_TOKEN_CLIENT_PEER_ADDRESS,
_WSI_TOKEN_CLIENT_URI,
_WSI_TOKEN_CLIENT_HOST,
_WSI_TOKEN_CLIENT_ORIGIN,
/* always last real token index*/
WSI_TOKEN_COUNT,
/* parser state additions */
WSI_TOKEN_NAME_PART,
WSI_TOKEN_SKIPPING,
WSI_TOKEN_SKIPPING_SAW_CR,
WSI_PARSING_COMPLETE,
WSI_INIT_TOKEN_MUXURL,
};
/*
* From RFC 6455
1000
1000 indicates a normal closure, meaning that the purpose for
which the connection was established has been fulfilled.
1001
1001 indicates that an endpoint is "going away", such as a server
going down or a browser having navigated away from a page.
1002
1002 indicates that an endpoint is terminating the connection due
to a protocol error.
1003
1003 indicates that an endpoint is terminating the connection
because it has received a type of data it cannot accept (e.g., an
endpoint that understands only text data MAY send this if it
receives a binary message).
1004
Reserved. The specific meaning might be defined in the future.
1005
1005 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that no status
code was actually present.
1006
1006 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed abnormally, e.g., without sending or
receiving a Close control frame.
1007
1007 indicates that an endpoint is terminating the connection
because it has received data within a message that was not
consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
data within a text message).
1008
1008 indicates that an endpoint is terminating the connection
because it has received a message that violates its policy. This
is a generic status code that can be returned when there is no
other more suitable status code (e.g., 1003 or 1009) or if there
is a need to hide specific details about the policy.
1009
1009 indicates that an endpoint is terminating the connection
because it has received a message that is too big for it to
process.
1010
1010 indicates that an endpoint (client) is terminating the
connection because it has expected the server to negotiate one or
more extension, but the server didn't return them in the response
message of the WebSocket handshake. The list of extensions that
are needed SHOULD appear in the /reason/ part of the Close frame.
Note that this status code is not used by the server, because it
can fail the WebSocket handshake instead.
1011
1011 indicates that a server is terminating the connection because
it encountered an unexpected condition that prevented it from
fulfilling the request.
1015
1015 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed due to a failure to perform a TLS handshake
(e.g., the server certificate can't be verified).
*/
enum lws_close_status {
LWS_CLOSE_STATUS_NOSTATUS = 0,
LWS_CLOSE_STATUS_NORMAL = 1000,
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
LWS_CLOSE_STATUS_RESERVED = 1004,
LWS_CLOSE_STATUS_NO_STATUS = 1005,
LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006,
LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007,
LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008,
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009,
LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010,
LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011,
LWS_CLOSE_STATUS_TLS_FAILURE = 1015,
};
struct libwebsocket;
struct libwebsocket_context;
/* needed even with extensions disabled for create context */
struct libwebsocket_extension;
/**
* callback_function() - User server actions
* @context: Websockets context
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with libwebsocket_create_server.
*
* You get an opportunity to initialize user data when called back with
* LWS_CALLBACK_ESTABLISHED reason.
*
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
* an incoming client
*
* LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has
* been unable to complete a handshake with the remote server
*
* LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the
* client user code to examine the http headers
* and decide to reject the connection. If the
* content in the headers is interesting to the
* client (url, etc) it needs to copy it out at
* this point since it will be destroyed before
* the CLIENT_ESTABLISHED call
*
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
* a handshake with the remote server
*
* LWS_CALLBACK_CLOSED: when the websocket session ends
*
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
* remote client, it can be found at *in and is
* len bytes long
*
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
* they appear with this callback reason. PONG
* packets only exist in 04+ protocol
*
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
* client connection, it can be found at *in and
* is len bytes long
*
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* @in points to the URI path requested and
* libwebsockets_serve_http_file() makes it very
* simple to send back a file to the client.
* Normally after sending the file you are done
* with the http connection, since the rest of the
* activity will come by websockets from the script
* that was delivered by http, so you will want to
* return 1; to close and free up the connection.
* That's important because it uses a slot in the
* total number of client connections allowed set
* by MAX_CLIENTS.
*
* LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protocol
* link now.
*
* LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down
* http link has completed.
*
* LWS_CALLBACK_CLIENT_WRITEABLE:
* LWS_CALLBACK_SERVER_WRITEABLE: If you call
* libwebsocket_callback_on_writable() on a connection, you will
* get one of these callbacks coming when the connection socket
* is able to accept another write packet without blocking.
* If it already was able to take another packet without blocking,
* you'll get this callback at the next call to the service loop
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
* and servers get LWS_CALLBACK_SERVER_WRITEABLE.
*
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. @in contains the connection
* socket's descriptor. Return non-zero to terminate
* the connection before sending or receiving anything.
* Because this happens immediately after the network connection
* from the client, there's no websocket protocol selected yet so
* this callback is issued only to protocol 0.
*
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* @user is a pointer to an array of struct lws_tokens, you can
* use the header enums lws_token_indexes from libwebsockets.h
* to check for and read the supported header presence and
* content before deciding to allow the handshake to proceed or
* to kill the connection.
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to perform extra SSL_CTX_load_verify_locations() or similar
* calls to direct OpenSSL where to find certificates the client
* can use to confirm the remote server identity. @user is the
* OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to load extra certifcates into the server which allow it to
* verify the validity of certificates returned by clients. @user
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* libwebsockets context was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, @user is the x509_ctx,
* @in is the ssl pointer and @len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates.
*
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens
* when a client handshake is being compiled. @user is NULL,
* @in is a char **, it's pointing to a char * which holds the
* next location in the header buffer where you can add
* headers, and @len is the remaining space in the header buffer,
* which is typically some hundreds of bytes. So, to add a canned
* cookie, your handler code might look similar to:
*
* char **p = (char **)in;
*
* if (len < 100)
* return 1;
*
* *p += sprintf(*p, "Cookie: a=b\x0d\x0a");
*
* return 0;
*
* Notice if you add anything, you just have to take care about
* the CRLF on the line you added. Obviously this callback is
* optional, if you don't handle it everything is fine.
*
* Notice the callback is coming to protocols[0] all the time,
* because there is no specific protocol handshook yet.
*
* LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code
* sees that it does support a requested extension, before
* accepting the extension by additing to the list sent back to
* the client it gives this callback just to check that it's okay
* to use that extension. It calls back to the requested protocol
* and with @in being the extension name, @len is 0 and @user is
* valid. Note though at this time the ESTABLISHED callback hasn't
* happened yet so if you initialize @user content there, @user
* content during this callback might not be useful for anything.
* Notice this callback comes to protocols[0].
*
* LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client
* connection is being prepared to start a handshake to a server,
* each supported extension is checked with protocols[0] callback
* with this reason, giving the user code a chance to suppress the
* claim to support that extension by returning non-zero. If
* unhandled, by default 0 will be returned and the extension
* support included in the header to the server. Notice this
* callback comes to protocols[0].
*
* LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can
* do initial setup / allocations etc
*
* LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating
* this protocol won't get used at all after this callback, the
* context is getting destroyed. Take the opportunity to
* deallocate everything that was allocated by the protocol.
*
* The next four reasons are optional and only need taking care of if you
* will be integrating libwebsockets sockets into an external polling
* array.
*
* LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop
* internally, but in the case you are integrating with another
* server you will need to have libwebsocket sockets share a
* polling array with the other server. This and the other
* POLL_FD related callbacks let you put your specialized
* poll array interface code in the callback for protocol 0, the
* first protocol you support, usually the HTTP protocol in the
* serving case. This callback happens when a socket needs to be
* added to the polling loop: @in contains the fd, and
* @len is the events bitmap (like, POLLIN). If you are using the
* internal polling loop (the "service" callback), you can just
* ignore these callbacks.
*
* LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor
* needs to be removed from an external polling array. @in is
* the socket desricptor. If you are using the internal polling
* loop, you can just ignore it.
*
* LWS_CALLBACK_SET_MODE_POLL_FD: This callback happens when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should OR @len on to the events member of the pollfd
* struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*
* LWS_CALLBACK_CLEAR_MODE_POLL_FD: This callback occurs when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should AND ~@len on to the events member of the
* pollfd struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*/
LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
typedef int (callback_function)(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
#ifndef LWS_NO_EXTENSIONS
/**
* extension_callback_function() - Hooks to allow extensions to operate
* @context: Websockets context
* @ext: This extension
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* Each extension that is active on a particular connection receives
* callbacks during the connection lifetime to allow the extension to
* operate on websocket data and manage itself.
*
* Libwebsockets takes care of allocating and freeing "user" memory for
* each active extension on each connection. That is what is pointed to
* by the @user parameter.
*
* LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to
* select this extension from the list provided by the client,
* just before the server will send back the handshake accepting
* the connection with this extension active. This gives the
* extension a chance to initialize its connection context found
* in @user.
*
* LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
* but called when client is instantiating this extension. Some
* extensions will work the same on client and server side and then
* you can just merge handlers for both CONSTRUCTS.
*
* LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
* user data is deleted. This same callback is used whether you
* are in client or server instantiation context.
*
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
* it is passed to this callback to give the extension a chance to
* change the data, eg, decompress it. @user is pointing to the
* extension's private connection context data, @in is pointing
* to an lws_tokens struct, it consists of a char * pointer called
* token, and an int called token_len. At entry, these are
* set to point to the received buffer and set to the content
* length. If the extension will grow the content, it should use
* a new buffer allocated in its private user context data and
* set the pointed-to lws_tokens members to point to its buffer.
*
* LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the
* extension a chance to change websocket data just before it will
* be sent out. Using the same lws_token pointer scheme in @in,
* the extension can change the buffer and the length to be
* transmitted how it likes. Again if it wants to grow the
* buffer safely, it should copy the data into its own buffer and
* set the lws_tokens token pointer to it.
*/
LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
typedef int (extension_callback_function)(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
#endif
/**
* struct libwebsocket_protocols - List of protocols and handlers server
* supports.
* @name: Protocol name that must match the one given in the client
* Javascript new WebSocket(url, 'protocol') name
* @callback: The service callback used for this protocol. It allows the
* service action for an entire protocol to be encapsulated in
* the protocol-specific callback
* @per_session_data_size: Each new connection using this protocol gets
* this much memory allocated on connection establishment and
* freed on connection takedown. A pointer to this per-connection
* allocation is passed into the callback in the 'user' parameter
* @rx_buffer_size: if you want atomic frames delivered to the callback, you
* should set this to the size of the biggest legal frame that
* you support. If the frame size is exceeded, there is no
* error, but the buffer will spill to the user callback when
* full, which you can detect by using
* libwebsockets_remaining_packet_payload(). Notice that you
* just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING
* and post-padding are automatically also allocated on top.
* @owning_server: the server init call fills in this opaque pointer when
* registering this protocol with the server.
* @protocol_index: which protocol we are starting from zero
*
* This structure represents one protocol supported by the server. An
* array of these structures is passed to libwebsocket_create_server()
* allows as many protocols as you like to be handled by one server.
*/
struct libwebsocket_protocols {
const char *name;
callback_function *callback;
size_t per_session_data_size;
size_t rx_buffer_size;
/*
* below are filled in on server init and can be left uninitialized,
* no need for user to use them directly either
*/
struct libwebsocket_context *owning_server;
int protocol_index;
};
#ifndef LWS_NO_EXTENSIONS
/**
* struct libwebsocket_extension - An extension we know how to cope with
*
* @name: Formal extension name, eg, "deflate-stream"
* @callback: Service callback
* @per_session_data_size: Libwebsockets will auto-malloc this much
* memory for the use of the extension, a pointer
* to it comes in the @user callback parameter
* @per_context_private_data: Optional storage for this extension that
* is per-context, so it can track stuff across
* all sessions, etc, if it wants
*/
struct libwebsocket_extension {
const char *name;
extension_callback_function *callback;
size_t per_session_data_size;
void *per_context_private_data;
};
#endif
/**
* struct lws_context_creation_info: parameters to create context with
*
* @port: Port to listen on... you can use 0 to suppress listening on
* any port, that's what you want if you are not running a
* websocket server at all but just using it as a client
* @iface: NULL to bind the listen socket to all interfaces, or the
* interface name, eg, "eth2"
* @protocols: Array of structures listing supported protocols and a protocol-
* specific callback for each one. The list is ended with an
* entry that has a NULL callback pointer.
* It's not const because we write the owning_server member
* @extensions: NULL or array of libwebsocket_extension structs listing the
* extensions this context supports. If you configured with
* --without-extensions, you should give NULL here.
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
* to listen using SSL, set to the filepath to fetch the
* server cert from, otherwise NULL for unencrypted
* @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
* else ignored
* @ssl_ca_filepath: CA certificate filepath or NULL
* @ssl_cipher_list: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* or you can leave it as NULL to get "DEFAULT"
* @gid: group id to change to after setting listen socket, or -1.
* @uid: user id to change to after setting listen socket, or -1.
* @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
* @user: optional user pointer that can be recovered via the context
* pointer using libwebsocket_context_user
* @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to
* all libwebsocket sockets, client or server
* @ka_probes: if ka_time was nonzero, after the timeout expires how many
* times to try to get a response from the peer before giving up
* and killing the connection
* @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes
* attempt
*/
struct lws_context_creation_info {
int port;
const char *iface;
struct libwebsocket_protocols *protocols;
struct libwebsocket_extension *extensions;
const char *ssl_cert_filepath;
const char *ssl_private_key_filepath;
const char *ssl_ca_filepath;
const char *ssl_cipher_list;
int gid;
int uid;
unsigned int options;
void *user;
int ka_time;
int ka_probes;
int ka_interval;
};
LWS_VISIBLE LWS_EXTERN
void lws_set_log_level(int level,
void (*log_emit_function)(int level, const char *line));
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_syslog(int level, const char *line);
LWS_VISIBLE LWS_EXTERN struct libwebsocket_context *
libwebsocket_create_context(struct lws_context_creation_info *info);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_context_destroy(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service(struct libwebsocket_context *context, int timeout_ms);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service_fd(struct libwebsocket_context *context,
struct pollfd *pollfd);
LWS_VISIBLE LWS_EXTERN void *
libwebsocket_context_user(struct libwebsocket_context *context);
/*
* IMPORTANT NOTICE!
*
* When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
* buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
*
* This allows us to add protocol info before and after the data, and send as
* one packet on the network without payload copying, for maximum efficiency.
*
* So for example you need this kind of code to use libwebsocket_write with a
* 128-byte payload
*
* char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
*
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
*
* libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128,
* LWS_WRITE_TEXT);
*
* When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
* use the whole buffer without taking care of the above.
*/
/*
* this is the frame nonce plus two header plus 8 length
* there's an additional two for mux extension per mux nesting level
* 2 byte prepend on close will already fit because control frames cannot use
* the big length style
*/
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION))
#define LWS_SEND_BUFFER_POST_PADDING 4
LWS_VISIBLE LWS_EXTERN int
libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
enum libwebsocket_write_protocol protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
const char *content_type);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_is_final_fragment(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char
libwebsocket_get_reserved_bits(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_rx_flow_allow_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata);
LWS_VISIBLE LWS_EXTERN const char *
libwebsocket_canonical_hostname(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN void
libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct libwebsocket *wsi, int fd, char *name, int name_len,
char *rip, int rip_len);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len);
LWS_VISIBLE LWS_EXTERN int
lws_daemonize(const char *_lock_path);
LWS_VISIBLE LWS_EXTERN int
lws_send_pipe_choked(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
lws_frame_is_binary(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char *
libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md);
LWS_VISIBLE LWS_EXTERN int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN int
lws_b64_decode_string(const char *in, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN const char *
lws_get_library_version(void);
/* access to headers... only valid while headers valid */
LWS_VISIBLE LWS_EXTERN int
lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h);
LWS_VISIBLE LWS_EXTERN int
lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len,
enum lws_token_indexes h);
/*
* Note: this is not normally needed as a user api. It's provided in case it is
* useful when integrating with other app poll loop service code.
*/
LWS_VISIBLE LWS_EXTERN int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi,
unsigned char *buf, size_t len);
#ifndef LWS_NO_EXTENSIONS
LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions();
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,993 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef __LIBWEBSOCKET_H__
#define __LIBWEBSOCKET_H__
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include "../win32port/win32helpers/websock-w32.h"
#include "../win32port/win32helpers/gettimeofday.h"
#define strcasecmp stricmp
#define getdtablesize() 30000
typedef int ssize_t;
#define LWS_VISIBLE
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#else
#define LWS_EXTERN extern __declspec(dllimport)
#endif
#else
#define LWS_EXTERN
#endif
#else // NOT WIN32
#include <poll.h>
#include <unistd.h>
#if defined(__GNUC__)
#define LWS_VISIBLE __attribute__((visibility("default")))
#else
#define LWS_VISIBLE
#endif
#endif
#include <assert.h>
#ifndef LWS_EXTERN
#define LWS_EXTERN extern
#endif
#define CONTEXT_PORT_NO_LISTEN 0
#define MAX_MUX_RECURSION 2
enum lws_log_levels {
LLL_ERR = 1 << 0,
LLL_WARN = 1 << 1,
LLL_NOTICE = 1 << 2,
LLL_INFO = 1 << 3,
LLL_DEBUG = 1 << 4,
LLL_PARSER = 1 << 5,
LLL_HEADER = 1 << 6,
LLL_EXT = 1 << 7,
LLL_CLIENT = 1 << 8,
LLL_LATENCY = 1 << 9,
LLL_COUNT = 10 /* set to count of valid flags */
};
LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...);
/* notice, warn and log are always compiled in */
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__)
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__)
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
/*
* weaker logging can be deselected at configure time using --disable-debug
* that gets rid of the overhead of checking while keeping _warn and _err
* active
*/
#ifdef _DEBUG
#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__)
#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__)
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__)
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__)
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__)
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__)
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__)
LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len);
#else /* no debug */
#define lwsl_info(...)
#define lwsl_debug(...)
#define lwsl_parser(...)
#define lwsl_header(...)
#define lwsl_ext(...)
#define lwsl_client(...)
#define lwsl_latency(...)
#define lwsl_hexdump(a, b)
#endif
enum libwebsocket_context_options {
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
};
enum libwebsocket_callback_reasons {
LWS_CALLBACK_ESTABLISHED,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
LWS_CALLBACK_CLIENT_ESTABLISHED,
LWS_CALLBACK_CLOSED,
LWS_CALLBACK_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_SERVER_WRITEABLE,
LWS_CALLBACK_HTTP,
LWS_CALLBACK_HTTP_FILE_COMPLETION,
LWS_CALLBACK_HTTP_WRITEABLE,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
LWS_CALLBACK_PROTOCOL_INIT,
LWS_CALLBACK_PROTOCOL_DESTROY,
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD,
LWS_CALLBACK_DEL_POLL_FD,
LWS_CALLBACK_SET_MODE_POLL_FD,
LWS_CALLBACK_CLEAR_MODE_POLL_FD,
};
#ifndef LWS_NO_EXTENSIONS
enum libwebsocket_extension_callback_reasons {
LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE,
LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
LWS_EXT_CALLBACK_DESTROY,
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING,
LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
LWS_EXT_CALLBACK_1HZ,
LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
LWS_EXT_CALLBACK_IS_WRITEABLE,
LWS_EXT_CALLBACK_PAYLOAD_TX,
LWS_EXT_CALLBACK_PAYLOAD_RX,
};
#endif
enum libwebsocket_write_protocol {
LWS_WRITE_TEXT,
LWS_WRITE_BINARY,
LWS_WRITE_CONTINUATION,
LWS_WRITE_HTTP,
/* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,
LWS_WRITE_PONG,
/* flags */
LWS_WRITE_NO_FIN = 0x40,
/*
* client packet payload goes out on wire unmunged
* only useful for security tests since normal servers cannot
* decode the content if used
*/
LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
};
/*
* you need these to look at headers that have been parsed if using the
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum
* list below is absent, .token = NULL and token_len = 0. Otherwise .token
* points to .token_len chars containing that header content.
*/
struct lws_tokens {
char *token;
int token_len;
};
enum lws_token_indexes {
WSI_TOKEN_GET_URI,
WSI_TOKEN_HOST,
WSI_TOKEN_CONNECTION,
WSI_TOKEN_KEY1,
WSI_TOKEN_KEY2,
WSI_TOKEN_PROTOCOL,
WSI_TOKEN_UPGRADE,
WSI_TOKEN_ORIGIN,
WSI_TOKEN_DRAFT,
WSI_TOKEN_CHALLENGE,
/* new for 04 */
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
/* new for 05 */
WSI_TOKEN_EXTENSIONS,
/* client receives these */
WSI_TOKEN_ACCEPT,
WSI_TOKEN_NONCE,
WSI_TOKEN_HTTP,
WSI_TOKEN_MUXURL,
/* use token storage to stash these */
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
_WSI_TOKEN_CLIENT_PEER_ADDRESS,
_WSI_TOKEN_CLIENT_URI,
_WSI_TOKEN_CLIENT_HOST,
_WSI_TOKEN_CLIENT_ORIGIN,
/* always last real token index*/
WSI_TOKEN_COUNT,
/* parser state additions */
WSI_TOKEN_NAME_PART,
WSI_TOKEN_SKIPPING,
WSI_TOKEN_SKIPPING_SAW_CR,
WSI_PARSING_COMPLETE,
WSI_INIT_TOKEN_MUXURL,
};
/*
* From RFC 6455
1000
1000 indicates a normal closure, meaning that the purpose for
which the connection was established has been fulfilled.
1001
1001 indicates that an endpoint is "going away", such as a server
going down or a browser having navigated away from a page.
1002
1002 indicates that an endpoint is terminating the connection due
to a protocol error.
1003
1003 indicates that an endpoint is terminating the connection
because it has received a type of data it cannot accept (e.g., an
endpoint that understands only text data MAY send this if it
receives a binary message).
1004
Reserved. The specific meaning might be defined in the future.
1005
1005 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that no status
code was actually present.
1006
1006 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed abnormally, e.g., without sending or
receiving a Close control frame.
1007
1007 indicates that an endpoint is terminating the connection
because it has received data within a message that was not
consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
data within a text message).
1008
1008 indicates that an endpoint is terminating the connection
because it has received a message that violates its policy. This
is a generic status code that can be returned when there is no
other more suitable status code (e.g., 1003 or 1009) or if there
is a need to hide specific details about the policy.
1009
1009 indicates that an endpoint is terminating the connection
because it has received a message that is too big for it to
process.
1010
1010 indicates that an endpoint (client) is terminating the
connection because it has expected the server to negotiate one or
more extension, but the server didn't return them in the response
message of the WebSocket handshake. The list of extensions that
are needed SHOULD appear in the /reason/ part of the Close frame.
Note that this status code is not used by the server, because it
can fail the WebSocket handshake instead.
1011
1011 indicates that a server is terminating the connection because
it encountered an unexpected condition that prevented it from
fulfilling the request.
1015
1015 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed due to a failure to perform a TLS handshake
(e.g., the server certificate can't be verified).
*/
enum lws_close_status {
LWS_CLOSE_STATUS_NOSTATUS = 0,
LWS_CLOSE_STATUS_NORMAL = 1000,
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
LWS_CLOSE_STATUS_RESERVED = 1004,
LWS_CLOSE_STATUS_NO_STATUS = 1005,
LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006,
LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007,
LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008,
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009,
LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010,
LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011,
LWS_CLOSE_STATUS_TLS_FAILURE = 1015,
};
struct libwebsocket;
struct libwebsocket_context;
/* needed even with extensions disabled for create context */
struct libwebsocket_extension;
/**
* callback_function() - User server actions
* @context: Websockets context
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with libwebsocket_create_server.
*
* You get an opportunity to initialize user data when called back with
* LWS_CALLBACK_ESTABLISHED reason.
*
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
* an incoming client
*
* LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has
* been unable to complete a handshake with the remote server
*
* LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the
* client user code to examine the http headers
* and decide to reject the connection. If the
* content in the headers is interesting to the
* client (url, etc) it needs to copy it out at
* this point since it will be destroyed before
* the CLIENT_ESTABLISHED call
*
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
* a handshake with the remote server
*
* LWS_CALLBACK_CLOSED: when the websocket session ends
*
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
* remote client, it can be found at *in and is
* len bytes long
*
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
* they appear with this callback reason. PONG
* packets only exist in 04+ protocol
*
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
* client connection, it can be found at *in and
* is len bytes long
*
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* @in points to the URI path requested and
* libwebsockets_serve_http_file() makes it very
* simple to send back a file to the client.
* Normally after sending the file you are done
* with the http connection, since the rest of the
* activity will come by websockets from the script
* that was delivered by http, so you will want to
* return 1; to close and free up the connection.
* That's important because it uses a slot in the
* total number of client connections allowed set
* by MAX_CLIENTS.
*
* LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protocol
* link now.
*
* LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down
* http link has completed.
*
* LWS_CALLBACK_CLIENT_WRITEABLE:
* LWS_CALLBACK_SERVER_WRITEABLE: If you call
* libwebsocket_callback_on_writable() on a connection, you will
* get one of these callbacks coming when the connection socket
* is able to accept another write packet without blocking.
* If it already was able to take another packet without blocking,
* you'll get this callback at the next call to the service loop
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
* and servers get LWS_CALLBACK_SERVER_WRITEABLE.
*
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. @in contains the connection
* socket's descriptor. Return non-zero to terminate
* the connection before sending or receiving anything.
* Because this happens immediately after the network connection
* from the client, there's no websocket protocol selected yet so
* this callback is issued only to protocol 0.
*
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* @user is a pointer to an array of struct lws_tokens, you can
* use the header enums lws_token_indexes from libwebsockets.h
* to check for and read the supported header presence and
* content before deciding to allow the handshake to proceed or
* to kill the connection.
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to perform extra SSL_CTX_load_verify_locations() or similar
* calls to direct OpenSSL where to find certificates the client
* can use to confirm the remote server identity. @user is the
* OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to load extra certifcates into the server which allow it to
* verify the validity of certificates returned by clients. @user
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* libwebsockets context was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, @user is the x509_ctx,
* @in is the ssl pointer and @len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates.
*
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens
* when a client handshake is being compiled. @user is NULL,
* @in is a char **, it's pointing to a char * which holds the
* next location in the header buffer where you can add
* headers, and @len is the remaining space in the header buffer,
* which is typically some hundreds of bytes. So, to add a canned
* cookie, your handler code might look similar to:
*
* char **p = (char **)in;
*
* if (len < 100)
* return 1;
*
* *p += sprintf(*p, "Cookie: a=b\x0d\x0a");
*
* return 0;
*
* Notice if you add anything, you just have to take care about
* the CRLF on the line you added. Obviously this callback is
* optional, if you don't handle it everything is fine.
*
* Notice the callback is coming to protocols[0] all the time,
* because there is no specific protocol handshook yet.
*
* LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code
* sees that it does support a requested extension, before
* accepting the extension by additing to the list sent back to
* the client it gives this callback just to check that it's okay
* to use that extension. It calls back to the requested protocol
* and with @in being the extension name, @len is 0 and @user is
* valid. Note though at this time the ESTABLISHED callback hasn't
* happened yet so if you initialize @user content there, @user
* content during this callback might not be useful for anything.
* Notice this callback comes to protocols[0].
*
* LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client
* connection is being prepared to start a handshake to a server,
* each supported extension is checked with protocols[0] callback
* with this reason, giving the user code a chance to suppress the
* claim to support that extension by returning non-zero. If
* unhandled, by default 0 will be returned and the extension
* support included in the header to the server. Notice this
* callback comes to protocols[0].
*
* LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can
* do initial setup / allocations etc
*
* LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating
* this protocol won't get used at all after this callback, the
* context is getting destroyed. Take the opportunity to
* deallocate everything that was allocated by the protocol.
*
* The next four reasons are optional and only need taking care of if you
* will be integrating libwebsockets sockets into an external polling
* array.
*
* LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop
* internally, but in the case you are integrating with another
* server you will need to have libwebsocket sockets share a
* polling array with the other server. This and the other
* POLL_FD related callbacks let you put your specialized
* poll array interface code in the callback for protocol 0, the
* first protocol you support, usually the HTTP protocol in the
* serving case. This callback happens when a socket needs to be
* added to the polling loop: @in contains the fd, and
* @len is the events bitmap (like, POLLIN). If you are using the
* internal polling loop (the "service" callback), you can just
* ignore these callbacks.
*
* LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor
* needs to be removed from an external polling array. @in is
* the socket desricptor. If you are using the internal polling
* loop, you can just ignore it.
*
* LWS_CALLBACK_SET_MODE_POLL_FD: This callback happens when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should OR @len on to the events member of the pollfd
* struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*
* LWS_CALLBACK_CLEAR_MODE_POLL_FD: This callback occurs when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should AND ~@len on to the events member of the
* pollfd struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*/
LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
typedef int (callback_function)(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
#ifndef LWS_NO_EXTENSIONS
/**
* extension_callback_function() - Hooks to allow extensions to operate
* @context: Websockets context
* @ext: This extension
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* Each extension that is active on a particular connection receives
* callbacks during the connection lifetime to allow the extension to
* operate on websocket data and manage itself.
*
* Libwebsockets takes care of allocating and freeing "user" memory for
* each active extension on each connection. That is what is pointed to
* by the @user parameter.
*
* LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to
* select this extension from the list provided by the client,
* just before the server will send back the handshake accepting
* the connection with this extension active. This gives the
* extension a chance to initialize its connection context found
* in @user.
*
* LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
* but called when client is instantiating this extension. Some
* extensions will work the same on client and server side and then
* you can just merge handlers for both CONSTRUCTS.
*
* LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
* user data is deleted. This same callback is used whether you
* are in client or server instantiation context.
*
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
* it is passed to this callback to give the extension a chance to
* change the data, eg, decompress it. @user is pointing to the
* extension's private connection context data, @in is pointing
* to an lws_tokens struct, it consists of a char * pointer called
* token, and an int called token_len. At entry, these are
* set to point to the received buffer and set to the content
* length. If the extension will grow the content, it should use
* a new buffer allocated in its private user context data and
* set the pointed-to lws_tokens members to point to its buffer.
*
* LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the
* extension a chance to change websocket data just before it will
* be sent out. Using the same lws_token pointer scheme in @in,
* the extension can change the buffer and the length to be
* transmitted how it likes. Again if it wants to grow the
* buffer safely, it should copy the data into its own buffer and
* set the lws_tokens token pointer to it.
*/
LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
typedef int (extension_callback_function)(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
#endif
/**
* struct libwebsocket_protocols - List of protocols and handlers server
* supports.
* @name: Protocol name that must match the one given in the client
* Javascript new WebSocket(url, 'protocol') name
* @callback: The service callback used for this protocol. It allows the
* service action for an entire protocol to be encapsulated in
* the protocol-specific callback
* @per_session_data_size: Each new connection using this protocol gets
* this much memory allocated on connection establishment and
* freed on connection takedown. A pointer to this per-connection
* allocation is passed into the callback in the 'user' parameter
* @rx_buffer_size: if you want atomic frames delivered to the callback, you
* should set this to the size of the biggest legal frame that
* you support. If the frame size is exceeded, there is no
* error, but the buffer will spill to the user callback when
* full, which you can detect by using
* libwebsockets_remaining_packet_payload(). Notice that you
* just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING
* and post-padding are automatically also allocated on top.
* @owning_server: the server init call fills in this opaque pointer when
* registering this protocol with the server.
* @protocol_index: which protocol we are starting from zero
*
* This structure represents one protocol supported by the server. An
* array of these structures is passed to libwebsocket_create_server()
* allows as many protocols as you like to be handled by one server.
*/
struct libwebsocket_protocols {
const char *name;
callback_function *callback;
size_t per_session_data_size;
size_t rx_buffer_size;
/*
* below are filled in on server init and can be left uninitialized,
* no need for user to use them directly either
*/
struct libwebsocket_context *owning_server;
int protocol_index;
};
#ifndef LWS_NO_EXTENSIONS
/**
* struct libwebsocket_extension - An extension we know how to cope with
*
* @name: Formal extension name, eg, "deflate-stream"
* @callback: Service callback
* @per_session_data_size: Libwebsockets will auto-malloc this much
* memory for the use of the extension, a pointer
* to it comes in the @user callback parameter
* @per_context_private_data: Optional storage for this extension that
* is per-context, so it can track stuff across
* all sessions, etc, if it wants
*/
struct libwebsocket_extension {
const char *name;
extension_callback_function *callback;
size_t per_session_data_size;
void *per_context_private_data;
};
#endif
/**
* struct lws_context_creation_info: parameters to create context with
*
* @port: Port to listen on... you can use 0 to suppress listening on
* any port, that's what you want if you are not running a
* websocket server at all but just using it as a client
* @iface: NULL to bind the listen socket to all interfaces, or the
* interface name, eg, "eth2"
* @protocols: Array of structures listing supported protocols and a protocol-
* specific callback for each one. The list is ended with an
* entry that has a NULL callback pointer.
* It's not const because we write the owning_server member
* @extensions: NULL or array of libwebsocket_extension structs listing the
* extensions this context supports. If you configured with
* --without-extensions, you should give NULL here.
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
* to listen using SSL, set to the filepath to fetch the
* server cert from, otherwise NULL for unencrypted
* @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
* else ignored
* @ssl_ca_filepath: CA certificate filepath or NULL
* @ssl_cipher_list: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* or you can leave it as NULL to get "DEFAULT"
* @gid: group id to change to after setting listen socket, or -1.
* @uid: user id to change to after setting listen socket, or -1.
* @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
* @user: optional user pointer that can be recovered via the context
* pointer using libwebsocket_context_user
* @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to
* all libwebsocket sockets, client or server
* @ka_probes: if ka_time was nonzero, after the timeout expires how many
* times to try to get a response from the peer before giving up
* and killing the connection
* @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes
* attempt
*/
struct lws_context_creation_info {
int port;
const char *iface;
struct libwebsocket_protocols *protocols;
struct libwebsocket_extension *extensions;
const char *ssl_cert_filepath;
const char *ssl_private_key_filepath;
const char *ssl_ca_filepath;
const char *ssl_cipher_list;
int gid;
int uid;
unsigned int options;
void *user;
int ka_time;
int ka_probes;
int ka_interval;
};
LWS_VISIBLE LWS_EXTERN
void lws_set_log_level(int level,
void (*log_emit_function)(int level, const char *line));
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_syslog(int level, const char *line);
LWS_VISIBLE LWS_EXTERN struct libwebsocket_context *
libwebsocket_create_context(struct lws_context_creation_info *info);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_context_destroy(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service(struct libwebsocket_context *context, int timeout_ms);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service_fd(struct libwebsocket_context *context,
struct pollfd *pollfd);
LWS_VISIBLE LWS_EXTERN void *
libwebsocket_context_user(struct libwebsocket_context *context);
/*
* IMPORTANT NOTICE!
*
* When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
* buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
*
* This allows us to add protocol info before and after the data, and send as
* one packet on the network without payload copying, for maximum efficiency.
*
* So for example you need this kind of code to use libwebsocket_write with a
* 128-byte payload
*
* char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
*
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
*
* libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128,
* LWS_WRITE_TEXT);
*
* When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
* use the whole buffer without taking care of the above.
*/
/*
* this is the frame nonce plus two header plus 8 length
* there's an additional two for mux extension per mux nesting level
* 2 byte prepend on close will already fit because control frames cannot use
* the big length style
*/
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION))
#define LWS_SEND_BUFFER_POST_PADDING 4
LWS_VISIBLE LWS_EXTERN int
libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
enum libwebsocket_write_protocol protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
const char *content_type);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_is_final_fragment(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char
libwebsocket_get_reserved_bits(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_rx_flow_allow_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata);
LWS_VISIBLE LWS_EXTERN const char *
libwebsocket_canonical_hostname(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN void
libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct libwebsocket *wsi, int fd, char *name, int name_len,
char *rip, int rip_len);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len);
LWS_VISIBLE LWS_EXTERN int
lws_daemonize(const char *_lock_path);
LWS_VISIBLE LWS_EXTERN int
lws_send_pipe_choked(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
lws_frame_is_binary(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char *
libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md);
LWS_VISIBLE LWS_EXTERN int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN int
lws_b64_decode_string(const char *in, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN const char *
lws_get_library_version(void);
/* access to headers... only valid while headers valid */
LWS_VISIBLE LWS_EXTERN int
lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h);
LWS_VISIBLE LWS_EXTERN int
lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len,
enum lws_token_indexes h);
/*
* Note: this is not normally needed as a user api. It's provided in case it is
* useful when integrating with other app poll loop service code.
*/
LWS_VISIBLE LWS_EXTERN int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi,
unsigned char *buf, size_t len);
#ifndef LWS_NO_EXTENSIONS
LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions();
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1 @@
ee4ee6cc26274f6d3138d08d429d6ba49b629f53

View File

@ -0,0 +1,993 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef __LIBWEBSOCKET_H__
#define __LIBWEBSOCKET_H__
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include "win32helpers/websock-w32.h"
//#include "win32helpers/gettimeofday.h"
#define strcasecmp stricmp
#define getdtablesize() 30000
typedef int ssize_t;
#define LWS_VISIBLE
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#else
#define LWS_EXTERN extern __declspec(dllimport)
#endif
#else
#define LWS_EXTERN
#endif
#else // NOT WIN32
#include <poll.h>
#include <unistd.h>
#if defined(__GNUC__)
#define LWS_VISIBLE __attribute__((visibility("default")))
#else
#define LWS_VISIBLE
#endif
#endif
#include <assert.h>
#ifndef LWS_EXTERN
#define LWS_EXTERN extern
#endif
#define CONTEXT_PORT_NO_LISTEN 0
#define MAX_MUX_RECURSION 2
enum lws_log_levels {
LLL_ERR = 1 << 0,
LLL_WARN = 1 << 1,
LLL_NOTICE = 1 << 2,
LLL_INFO = 1 << 3,
LLL_DEBUG = 1 << 4,
LLL_PARSER = 1 << 5,
LLL_HEADER = 1 << 6,
LLL_EXT = 1 << 7,
LLL_CLIENT = 1 << 8,
LLL_LATENCY = 1 << 9,
LLL_COUNT = 10 /* set to count of valid flags */
};
LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...);
/* notice, warn and log are always compiled in */
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__)
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__)
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
/*
* weaker logging can be deselected at configure time using --disable-debug
* that gets rid of the overhead of checking while keeping _warn and _err
* active
*/
#ifdef _DEBUG
#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__)
#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__)
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__)
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__)
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__)
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__)
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__)
LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len);
#else /* no debug */
#define lwsl_info(...)
#define lwsl_debug(...)
#define lwsl_parser(...)
#define lwsl_header(...)
#define lwsl_ext(...)
#define lwsl_client(...)
#define lwsl_latency(...)
#define lwsl_hexdump(a, b)
#endif
enum libwebsocket_context_options {
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
};
enum libwebsocket_callback_reasons {
LWS_CALLBACK_ESTABLISHED,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
LWS_CALLBACK_CLIENT_ESTABLISHED,
LWS_CALLBACK_CLOSED,
LWS_CALLBACK_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE,
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_SERVER_WRITEABLE,
LWS_CALLBACK_HTTP,
LWS_CALLBACK_HTTP_FILE_COMPLETION,
LWS_CALLBACK_HTTP_WRITEABLE,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
LWS_CALLBACK_PROTOCOL_INIT,
LWS_CALLBACK_PROTOCOL_DESTROY,
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD,
LWS_CALLBACK_DEL_POLL_FD,
LWS_CALLBACK_SET_MODE_POLL_FD,
LWS_CALLBACK_CLEAR_MODE_POLL_FD,
};
#ifndef LWS_NO_EXTENSIONS
enum libwebsocket_extension_callback_reasons {
LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT,
LWS_EXT_CALLBACK_CONSTRUCT,
LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE,
LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
LWS_EXT_CALLBACK_DESTROY,
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING,
LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
LWS_EXT_CALLBACK_1HZ,
LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE,
LWS_EXT_CALLBACK_IS_WRITEABLE,
LWS_EXT_CALLBACK_PAYLOAD_TX,
LWS_EXT_CALLBACK_PAYLOAD_RX,
};
#endif
enum libwebsocket_write_protocol {
LWS_WRITE_TEXT,
LWS_WRITE_BINARY,
LWS_WRITE_CONTINUATION,
LWS_WRITE_HTTP,
/* special 04+ opcodes */
LWS_WRITE_CLOSE,
LWS_WRITE_PING,
LWS_WRITE_PONG,
/* flags */
LWS_WRITE_NO_FIN = 0x40,
/*
* client packet payload goes out on wire unmunged
* only useful for security tests since normal servers cannot
* decode the content if used
*/
LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80
};
/*
* you need these to look at headers that have been parsed if using the
* LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum
* list below is absent, .token = NULL and token_len = 0. Otherwise .token
* points to .token_len chars containing that header content.
*/
struct lws_tokens {
char *token;
int token_len;
};
enum lws_token_indexes {
WSI_TOKEN_GET_URI,
WSI_TOKEN_HOST,
WSI_TOKEN_CONNECTION,
WSI_TOKEN_KEY1,
WSI_TOKEN_KEY2,
WSI_TOKEN_PROTOCOL,
WSI_TOKEN_UPGRADE,
WSI_TOKEN_ORIGIN,
WSI_TOKEN_DRAFT,
WSI_TOKEN_CHALLENGE,
/* new for 04 */
WSI_TOKEN_KEY,
WSI_TOKEN_VERSION,
WSI_TOKEN_SWORIGIN,
/* new for 05 */
WSI_TOKEN_EXTENSIONS,
/* client receives these */
WSI_TOKEN_ACCEPT,
WSI_TOKEN_NONCE,
WSI_TOKEN_HTTP,
WSI_TOKEN_MUXURL,
/* use token storage to stash these */
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
_WSI_TOKEN_CLIENT_PEER_ADDRESS,
_WSI_TOKEN_CLIENT_URI,
_WSI_TOKEN_CLIENT_HOST,
_WSI_TOKEN_CLIENT_ORIGIN,
/* always last real token index*/
WSI_TOKEN_COUNT,
/* parser state additions */
WSI_TOKEN_NAME_PART,
WSI_TOKEN_SKIPPING,
WSI_TOKEN_SKIPPING_SAW_CR,
WSI_PARSING_COMPLETE,
WSI_INIT_TOKEN_MUXURL,
};
/*
* From RFC 6455
1000
1000 indicates a normal closure, meaning that the purpose for
which the connection was established has been fulfilled.
1001
1001 indicates that an endpoint is "going away", such as a server
going down or a browser having navigated away from a page.
1002
1002 indicates that an endpoint is terminating the connection due
to a protocol error.
1003
1003 indicates that an endpoint is terminating the connection
because it has received a type of data it cannot accept (e.g., an
endpoint that understands only text data MAY send this if it
receives a binary message).
1004
Reserved. The specific meaning might be defined in the future.
1005
1005 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that no status
code was actually present.
1006
1006 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed abnormally, e.g., without sending or
receiving a Close control frame.
1007
1007 indicates that an endpoint is terminating the connection
because it has received data within a message that was not
consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
data within a text message).
1008
1008 indicates that an endpoint is terminating the connection
because it has received a message that violates its policy. This
is a generic status code that can be returned when there is no
other more suitable status code (e.g., 1003 or 1009) or if there
is a need to hide specific details about the policy.
1009
1009 indicates that an endpoint is terminating the connection
because it has received a message that is too big for it to
process.
1010
1010 indicates that an endpoint (client) is terminating the
connection because it has expected the server to negotiate one or
more extension, but the server didn't return them in the response
message of the WebSocket handshake. The list of extensions that
are needed SHOULD appear in the /reason/ part of the Close frame.
Note that this status code is not used by the server, because it
can fail the WebSocket handshake instead.
1011
1011 indicates that a server is terminating the connection because
it encountered an unexpected condition that prevented it from
fulfilling the request.
1015
1015 is a reserved value and MUST NOT be set as a status code in a
Close control frame by an endpoint. It is designated for use in
applications expecting a status code to indicate that the
connection was closed due to a failure to perform a TLS handshake
(e.g., the server certificate can't be verified).
*/
enum lws_close_status {
LWS_CLOSE_STATUS_NOSTATUS = 0,
LWS_CLOSE_STATUS_NORMAL = 1000,
LWS_CLOSE_STATUS_GOINGAWAY = 1001,
LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002,
LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003,
LWS_CLOSE_STATUS_RESERVED = 1004,
LWS_CLOSE_STATUS_NO_STATUS = 1005,
LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006,
LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007,
LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008,
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009,
LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010,
LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011,
LWS_CLOSE_STATUS_TLS_FAILURE = 1015,
};
struct libwebsocket;
struct libwebsocket_context;
/* needed even with extensions disabled for create context */
struct libwebsocket_extension;
/**
* callback_function() - User server actions
* @context: Websockets context
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with libwebsocket_create_server.
*
* You get an opportunity to initialize user data when called back with
* LWS_CALLBACK_ESTABLISHED reason.
*
* LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with
* an incoming client
*
* LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has
* been unable to complete a handshake with the remote server
*
* LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the
* client user code to examine the http headers
* and decide to reject the connection. If the
* content in the headers is interesting to the
* client (url, etc) it needs to copy it out at
* this point since it will be destroyed before
* the CLIENT_ESTABLISHED call
*
* LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed
* a handshake with the remote server
*
* LWS_CALLBACK_CLOSED: when the websocket session ends
*
* LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a
* remote client, it can be found at *in and is
* len bytes long
*
* LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets,
* they appear with this callback reason. PONG
* packets only exist in 04+ protocol
*
* LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the
* client connection, it can be found at *in and
* is len bytes long
*
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* @in points to the URI path requested and
* libwebsockets_serve_http_file() makes it very
* simple to send back a file to the client.
* Normally after sending the file you are done
* with the http connection, since the rest of the
* activity will come by websockets from the script
* that was delivered by http, so you will want to
* return 1; to close and free up the connection.
* That's important because it uses a slot in the
* total number of client connections allowed set
* by MAX_CLIENTS.
*
* LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protocol
* link now.
*
* LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down
* http link has completed.
*
* LWS_CALLBACK_CLIENT_WRITEABLE:
* LWS_CALLBACK_SERVER_WRITEABLE: If you call
* libwebsocket_callback_on_writable() on a connection, you will
* get one of these callbacks coming when the connection socket
* is able to accept another write packet without blocking.
* If it already was able to take another packet without blocking,
* you'll get this callback at the next call to the service loop
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
* and servers get LWS_CALLBACK_SERVER_WRITEABLE.
*
* LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP. @in contains the connection
* socket's descriptor. Return non-zero to terminate
* the connection before sending or receiving anything.
* Because this happens immediately after the network connection
* from the client, there's no websocket protocol selected yet so
* this callback is issued only to protocol 0.
*
* LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* @user is a pointer to an array of struct lws_tokens, you can
* use the header enums lws_token_indexes from libwebsockets.h
* to check for and read the supported header presence and
* content before deciding to allow the handshake to proceed or
* to kill the connection.
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to perform extra SSL_CTX_load_verify_locations() or similar
* calls to direct OpenSSL where to find certificates the client
* can use to confirm the remote server identity. @user is the
* OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for
* including OpenSSL support, this callback allows your user code
* to load extra certifcates into the server which allow it to
* verify the validity of certificates returned by clients. @user
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* libwebsockets context was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, @user is the x509_ctx,
* @in is the ssl pointer and @len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates.
*
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens
* when a client handshake is being compiled. @user is NULL,
* @in is a char **, it's pointing to a char * which holds the
* next location in the header buffer where you can add
* headers, and @len is the remaining space in the header buffer,
* which is typically some hundreds of bytes. So, to add a canned
* cookie, your handler code might look similar to:
*
* char **p = (char **)in;
*
* if (len < 100)
* return 1;
*
* *p += sprintf(*p, "Cookie: a=b\x0d\x0a");
*
* return 0;
*
* Notice if you add anything, you just have to take care about
* the CRLF on the line you added. Obviously this callback is
* optional, if you don't handle it everything is fine.
*
* Notice the callback is coming to protocols[0] all the time,
* because there is no specific protocol handshook yet.
*
* LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code
* sees that it does support a requested extension, before
* accepting the extension by additing to the list sent back to
* the client it gives this callback just to check that it's okay
* to use that extension. It calls back to the requested protocol
* and with @in being the extension name, @len is 0 and @user is
* valid. Note though at this time the ESTABLISHED callback hasn't
* happened yet so if you initialize @user content there, @user
* content during this callback might not be useful for anything.
* Notice this callback comes to protocols[0].
*
* LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client
* connection is being prepared to start a handshake to a server,
* each supported extension is checked with protocols[0] callback
* with this reason, giving the user code a chance to suppress the
* claim to support that extension by returning non-zero. If
* unhandled, by default 0 will be returned and the extension
* support included in the header to the server. Notice this
* callback comes to protocols[0].
*
* LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can
* do initial setup / allocations etc
*
* LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating
* this protocol won't get used at all after this callback, the
* context is getting destroyed. Take the opportunity to
* deallocate everything that was allocated by the protocol.
*
* The next four reasons are optional and only need taking care of if you
* will be integrating libwebsockets sockets into an external polling
* array.
*
* LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop
* internally, but in the case you are integrating with another
* server you will need to have libwebsocket sockets share a
* polling array with the other server. This and the other
* POLL_FD related callbacks let you put your specialized
* poll array interface code in the callback for protocol 0, the
* first protocol you support, usually the HTTP protocol in the
* serving case. This callback happens when a socket needs to be
* added to the polling loop: @in contains the fd, and
* @len is the events bitmap (like, POLLIN). If you are using the
* internal polling loop (the "service" callback), you can just
* ignore these callbacks.
*
* LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor
* needs to be removed from an external polling array. @in is
* the socket desricptor. If you are using the internal polling
* loop, you can just ignore it.
*
* LWS_CALLBACK_SET_MODE_POLL_FD: This callback happens when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should OR @len on to the events member of the pollfd
* struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*
* LWS_CALLBACK_CLEAR_MODE_POLL_FD: This callback occurs when libwebsockets
* wants to modify the events for the socket descriptor in @in.
* The handler should AND ~@len on to the events member of the
* pollfd struct for this socket descriptor. If you are using the
* internal polling loop, you can just ignore it.
*/
LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
typedef int (callback_function)(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
#ifndef LWS_NO_EXTENSIONS
/**
* extension_callback_function() - Hooks to allow extensions to operate
* @context: Websockets context
* @ext: This extension
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* Each extension that is active on a particular connection receives
* callbacks during the connection lifetime to allow the extension to
* operate on websocket data and manage itself.
*
* Libwebsockets takes care of allocating and freeing "user" memory for
* each active extension on each connection. That is what is pointed to
* by the @user parameter.
*
* LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to
* select this extension from the list provided by the client,
* just before the server will send back the handshake accepting
* the connection with this extension active. This gives the
* extension a chance to initialize its connection context found
* in @user.
*
* LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT
* but called when client is instantiating this extension. Some
* extensions will work the same on client and server side and then
* you can just merge handlers for both CONSTRUCTS.
*
* LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was
* being used on is about to be closed and deallocated. It's the
* last chance for the extension to deallocate anything it has
* allocated in the user data (pointed to by @user) before the
* user data is deleted. This same callback is used whether you
* are in client or server instantiation context.
*
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on
* a connection, and a packet of data arrived at the connection,
* it is passed to this callback to give the extension a chance to
* change the data, eg, decompress it. @user is pointing to the
* extension's private connection context data, @in is pointing
* to an lws_tokens struct, it consists of a char * pointer called
* token, and an int called token_len. At entry, these are
* set to point to the received buffer and set to the content
* length. If the extension will grow the content, it should use
* a new buffer allocated in its private user context data and
* set the pointed-to lws_tokens members to point to its buffer.
*
* LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as
* LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the
* extension a chance to change websocket data just before it will
* be sent out. Using the same lws_token pointer scheme in @in,
* the extension can change the buffer and the length to be
* transmitted how it likes. Again if it wants to grow the
* buffer safely, it should copy the data into its own buffer and
* set the lws_tokens token pointer to it.
*/
LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
typedef int (extension_callback_function)(struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
#endif
/**
* struct libwebsocket_protocols - List of protocols and handlers server
* supports.
* @name: Protocol name that must match the one given in the client
* Javascript new WebSocket(url, 'protocol') name
* @callback: The service callback used for this protocol. It allows the
* service action for an entire protocol to be encapsulated in
* the protocol-specific callback
* @per_session_data_size: Each new connection using this protocol gets
* this much memory allocated on connection establishment and
* freed on connection takedown. A pointer to this per-connection
* allocation is passed into the callback in the 'user' parameter
* @rx_buffer_size: if you want atomic frames delivered to the callback, you
* should set this to the size of the biggest legal frame that
* you support. If the frame size is exceeded, there is no
* error, but the buffer will spill to the user callback when
* full, which you can detect by using
* libwebsockets_remaining_packet_payload(). Notice that you
* just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING
* and post-padding are automatically also allocated on top.
* @owning_server: the server init call fills in this opaque pointer when
* registering this protocol with the server.
* @protocol_index: which protocol we are starting from zero
*
* This structure represents one protocol supported by the server. An
* array of these structures is passed to libwebsocket_create_server()
* allows as many protocols as you like to be handled by one server.
*/
struct libwebsocket_protocols {
const char *name;
callback_function *callback;
size_t per_session_data_size;
size_t rx_buffer_size;
/*
* below are filled in on server init and can be left uninitialized,
* no need for user to use them directly either
*/
struct libwebsocket_context *owning_server;
int protocol_index;
};
#ifndef LWS_NO_EXTENSIONS
/**
* struct libwebsocket_extension - An extension we know how to cope with
*
* @name: Formal extension name, eg, "deflate-stream"
* @callback: Service callback
* @per_session_data_size: Libwebsockets will auto-malloc this much
* memory for the use of the extension, a pointer
* to it comes in the @user callback parameter
* @per_context_private_data: Optional storage for this extension that
* is per-context, so it can track stuff across
* all sessions, etc, if it wants
*/
struct libwebsocket_extension {
const char *name;
extension_callback_function *callback;
size_t per_session_data_size;
void *per_context_private_data;
};
#endif
/**
* struct lws_context_creation_info: parameters to create context with
*
* @port: Port to listen on... you can use 0 to suppress listening on
* any port, that's what you want if you are not running a
* websocket server at all but just using it as a client
* @iface: NULL to bind the listen socket to all interfaces, or the
* interface name, eg, "eth2"
* @protocols: Array of structures listing supported protocols and a protocol-
* specific callback for each one. The list is ended with an
* entry that has a NULL callback pointer.
* It's not const because we write the owning_server member
* @extensions: NULL or array of libwebsocket_extension structs listing the
* extensions this context supports. If you configured with
* --without-extensions, you should give NULL here.
* @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want
* to listen using SSL, set to the filepath to fetch the
* server cert from, otherwise NULL for unencrypted
* @ssl_private_key_filepath: filepath to private key if wanting SSL mode,
* else ignored
* @ssl_ca_filepath: CA certificate filepath or NULL
* @ssl_cipher_list: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* or you can leave it as NULL to get "DEFAULT"
* @gid: group id to change to after setting listen socket, or -1.
* @uid: user id to change to after setting listen socket, or -1.
* @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK
* @user: optional user pointer that can be recovered via the context
* pointer using libwebsocket_context_user
* @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to
* all libwebsocket sockets, client or server
* @ka_probes: if ka_time was nonzero, after the timeout expires how many
* times to try to get a response from the peer before giving up
* and killing the connection
* @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes
* attempt
*/
struct lws_context_creation_info {
int port;
const char *iface;
struct libwebsocket_protocols *protocols;
struct libwebsocket_extension *extensions;
const char *ssl_cert_filepath;
const char *ssl_private_key_filepath;
const char *ssl_ca_filepath;
const char *ssl_cipher_list;
int gid;
int uid;
unsigned int options;
void *user;
int ka_time;
int ka_probes;
int ka_interval;
};
LWS_VISIBLE LWS_EXTERN
void lws_set_log_level(int level,
void (*log_emit_function)(int level, const char *line));
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_syslog(int level, const char *line);
LWS_VISIBLE LWS_EXTERN struct libwebsocket_context *
libwebsocket_create_context(struct lws_context_creation_info *info);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_context_destroy(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service(struct libwebsocket_context *context, int timeout_ms);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_service_fd(struct libwebsocket_context *context,
struct pollfd *pollfd);
LWS_VISIBLE LWS_EXTERN void *
libwebsocket_context_user(struct libwebsocket_context *context);
/*
* IMPORTANT NOTICE!
*
* When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY)
* the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE
* buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len).
*
* This allows us to add protocol info before and after the data, and send as
* one packet on the network without payload copying, for maximum efficiency.
*
* So for example you need this kind of code to use libwebsocket_write with a
* 128-byte payload
*
* char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
*
* // fill your part of the buffer... for example here it's all zeros
* memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
*
* libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128,
* LWS_WRITE_TEXT);
*
* When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
* use the whole buffer without taking care of the above.
*/
/*
* this is the frame nonce plus two header plus 8 length
* there's an additional two for mux extension per mux nesting level
* 2 byte prepend on close will already fit because control frames cannot use
* the big length style
*/
#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION))
#define LWS_SEND_BUFFER_POST_PADDING 4
LWS_VISIBLE LWS_EXTERN int
libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len,
enum libwebsocket_write_protocol protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
const char *content_type);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_get_socket_fd(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_is_final_fragment(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char
libwebsocket_get_reserved_bits(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_rx_flow_allow_all_protocol(
const struct libwebsocket_protocols *protocol);
LWS_VISIBLE LWS_EXTERN size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one);
LWS_VISIBLE LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *clients,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata);
LWS_VISIBLE LWS_EXTERN const char *
libwebsocket_canonical_hostname(struct libwebsocket_context *context);
LWS_VISIBLE LWS_EXTERN void
libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct libwebsocket *wsi, int fd, char *name, int name_len,
char *rip, int rip_len);
LWS_VISIBLE LWS_EXTERN int
libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len);
LWS_VISIBLE LWS_EXTERN int
lws_daemonize(const char *_lock_path);
LWS_VISIBLE LWS_EXTERN int
lws_send_pipe_choked(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
lws_frame_is_binary(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN unsigned char *
libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md);
LWS_VISIBLE LWS_EXTERN int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN int
lws_b64_decode_string(const char *in, char *out, int out_size);
LWS_VISIBLE LWS_EXTERN const char *
lws_get_library_version(void);
/* access to headers... only valid while headers valid */
LWS_VISIBLE LWS_EXTERN int
lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h);
LWS_VISIBLE LWS_EXTERN int
lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len,
enum lws_token_indexes h);
/*
* Note: this is not normally needed as a user api. It's provided in case it is
* useful when integrating with other app poll loop service code.
*/
LWS_VISIBLE LWS_EXTERN int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi,
unsigned char *buf, size_t len);
#ifndef LWS_NO_EXTENSIONS
LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions();
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,28 @@
#ifndef _GET_TIME_OF_DAY_H
#define _GET_TIME_OF_DAY_H
#ifdef __MINGW64__
#else
#ifdef __MINGW32__
#else
#include < time.h >
#endif
#endif
#include <windows.h> //I've ommited context line.
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif

View File

@ -0,0 +1,62 @@
#ifndef __WEB_SOCK_W32_H__
#define __WEB_SOCK_W32_H__
// Windows uses _DEBUG and NDEBUG
#ifdef _DEBUG
#undef DEBUG
#define DEBUG 1
#endif
#pragma warning(disable : 4996)
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#define MSG_NOSIGNAL 0
#define SHUT_RDWR SD_BOTH
#define SOL_TCP IPPROTO_TCP
#define random rand
#define usleep _sleep
#ifdef __MINGW64__
#define DEF_POLL_STUFF
#endif
#ifdef __MINGW32__
#define DEF_POLL_STUFF
#endif
#ifdef DEF_POLL_STUFF
#include <winsock2.h>
typedef struct pollfd {
SOCKET fd;
short events;
short revents;
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
#define POLLIN 0x0001 /* any readable data available */
#define POLLOUT 0x0004 /* file descriptor is writeable */
#define POLLERR 0x0008 /* some poll error occurred */
#define POLLHUP 0x0010 /* file descriptor was "hung up" */
#define POLLNVAL 0x0020 /* requested events "invalid" */
#endif
typedef INT (WSAAPI *PFNWSAPOLL)(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout);
extern PFNWSAPOLL poll;
extern INT WSAAPI emulated_poll(LPWSAPOLLFD fdarray, ULONG nfds, INT timeout);
/* override configure because we are not using Makefiles */
#define LWS_NO_FORK
/* windows can't cope with this idea, needs assets in cwd */
#ifndef INSTALL_DATADIR
#define INSTALL_DATADIR "."
#endif
#endif

View File

@ -0,0 +1,526 @@
Libwebsockets and included programs are provided under the terms of the GNU
Library General Public License (LGPL) 2.1, with the following exceptions:
1) Static linking of programs with the libwebsockets library does not
constitute a derivative work and does not require the author to provide
source code for the program, use the shared libwebsockets libraries, or
link their program against a user-supplied version of libwebsockets.
If you link the program to a modified version of libwebsockets, then the
changes to libwebsockets must be provided under the terms of the LGPL in
sections 1, 2, and 4.
2) You do not have to provide a copy of the libwebsockets license with
programs that are linked to the libwebsockets library, nor do you have to
identify the libwebsockets license in your program or documentation as
required by section 6 of the LGPL.
However, programs must still identify their use of libwebsockets. The
following example statement can be included in user documentation to
satisfy this requirement:
"[program] is based in part on the work of the libwebsockets project
(http://libwebsockets.org)"
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,96 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCX_ADS_ADMOB_H__
#define __CCX_ADS_ADMOB_H__
#include "ProtocolAds.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
class AdsAdmob : public ProtocolAds
{
PLUGIN_REGISTER_DECL(AdsAdmob)
public:
typedef enum {
kSizeBanner = 0,
kSizeIABMRect,
kSizeIABBanner,
kSizeIABLeaderboard,
} AdmobBannerSize;
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief config the application info
@param devInfo This parameter is the info of application, must contains:
AdmobID The publisher ID of admob.
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void configDeveloperInfo(TAdsDeveloperInfo devInfo);
/**
@brief show adview
@param type The adview type need to show.
@param sizeEnum The size of the banner view.
(only used when type is kBannerAd)
Use the enum number in AdmobBannerSize.
@param pos The position where the adview be shown.
(only used when type is kBannerAd)
*/
virtual void showAds(AdsType type, int sizeEnum = 0, AdsPos pos = kPosCenter);
/**
@brief Hide the adview
@param type The adview type need to hide.
*/
virtual void hideAds(AdsType type);
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
/**
@brief Add the test device ID
@param deviceID The device ID
*/
void addTestDevice(const char* deviceID);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
virtual ~AdsAdmob();
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_ADS_ADMOB_H__ */

View File

@ -1,60 +0,0 @@
[admob]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = pluginx_admob
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = plugin
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include/linux -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include -I%(androidndkdir)s/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.6/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
clang_flags = -nostdinc -x c++
cocos_headers = -I%(pluginxdir)s/protocols/include -I%(pluginxdir)s/plugins/admob/include
cocos_flags = -DANDROID
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s
# what headers to parse
headers = %(pluginxdir)s/plugins/admob/include/AdsAdmob.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^CCMenu*$".
classes = AdsAdmob
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = *::[createPlugin]
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# CCSet is special and we will use a hand-written constructor
abstract_classes = AdsAdmob
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

View File

@ -1,81 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "AdsAdmob.h"
#include "PluginUtils.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(AdsAdmob)
AdsAdmob::~AdsAdmob()
{
}
bool AdsAdmob::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.AdsAdmob");
}
void AdsAdmob::configDeveloperInfo(TAdsDeveloperInfo appInfo)
{
ProtocolAds::configDeveloperInfo(appInfo);
}
void AdsAdmob::showAds(AdsType type, int sizeEnum, AdsPos pos)
{
ProtocolAds::showAds(type, sizeEnum, pos);
}
void AdsAdmob::hideAds(AdsType type)
{
ProtocolAds::hideAds(type);
}
const char* AdsAdmob::getSDKVersion()
{
return ProtocolAds::getSDKVersion();
}
void AdsAdmob::setDebugMode(bool debug)
{
ProtocolAds::setDebugMode(debug);
}
void AdsAdmob::addTestDevice(const char* deviceID)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "addTestDevice"
, "(Ljava/lang/String;)V"))
{
jstring strDeviceID = t.env->NewStringUTF(deviceID);
t.env->CallVoidMethod(pData->jobj, t.methodID, strDeviceID);
t.env->DeleteLocalRef(strDeviceID);
t.env->DeleteLocalRef(t.classID);
}
}
}} // namespace cocos2d { namespace plugin {

View File

@ -30,16 +30,4 @@
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,20 +0,0 @@
# set params
PLUGIN_ANDROID_ROOT=$(cd "$(dirname "$0")"; pwd)
if [ ! "${PLUGIN_ROOT}" ]; then
PLUGIN_ROOT="$PLUGIN_ANDROID_ROOT"/../..
fi
# build
"$ANDROID_NDK_ROOT"/ndk-build -C "$PLUGIN_ANDROID_ROOT" \
NDK_MODULE_PATH="$PLUGIN_ROOT"
echo
if [ "0" != "$?" ]; then
echo "Build error occoured!!!"
exit 1
fi
echo
echo "Native build action success."
exit 0

View File

@ -1,29 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PluginAdmobStatic
LOCAL_MODULE_FILENAME := libPluginAdmobStatic
LOCAL_SRC_FILES := \
$(addprefix ../../platform/android/, \
AdsAdmob.cpp \
) \
LOCAL_CFLAGS :=
LOCAL_EXPORT_CFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module, protocols/proj.android/jni)

View File

@ -1,7 +0,0 @@
# it is needed for ndk-r5
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_MODULES := PluginAdmobStatic
APP_ABI :=armeabi
#APP_ABI :=x86
#APP_ABI :=mips mips-r2 mips-r2-sf armeabi

View File

@ -28,8 +28,6 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import org.cocos2dx.plugin.InterfaceAds.AdsAdapter;
import com.google.ads.*;
import com.google.ads.AdRequest.ErrorCode;
@ -38,7 +36,7 @@ import android.content.Context;
import android.util.Log;
import android.view.WindowManager;
public class AdsAdmob implements AdsAdapter {
public class AdsAdmob implements InterfaceAds {
private static final String LOG_TAG = "AdsAdmob";
private static Activity mContext = null;
@ -94,10 +92,10 @@ public class AdsAdmob implements AdsAdapter {
@Override
public void showAds(int adsType, int sizeEnum, int pos) {
switch (adsType) {
case InterfaceAds.ADS_TYPE_BANNER:
case AdsWrapper.ADS_TYPE_BANNER:
showBannerAd(sizeEnum, pos);
break;
case InterfaceAds.ADS_TYPE_FULL_SCREEN:
case AdsWrapper.ADS_TYPE_FULL_SCREEN:
LogD("Now not support full screen view in Admob");
break;
default:
@ -113,10 +111,10 @@ public class AdsAdmob implements AdsAdapter {
@Override
public void hideAds(int adsType) {
switch (adsType) {
case InterfaceAds.ADS_TYPE_BANNER:
case AdsWrapper.ADS_TYPE_BANNER:
hideBannerAd();
break;
case InterfaceAds.ADS_TYPE_FULL_SCREEN:
case AdsWrapper.ADS_TYPE_FULL_SCREEN:
break;
default:
break;
@ -178,7 +176,7 @@ public class AdsAdmob implements AdsAdapter {
if (null == mWm) {
mWm = (WindowManager) mContext.getSystemService("window");
}
InterfaceAds.addAdView(mWm, adView, curPos);
AdsWrapper.addAdView(mWm, adView, curPos);
}
});
}
@ -211,20 +209,20 @@ public class AdsAdmob implements AdsAdapter {
@Override
public void onDismissScreen(Ad arg0) {
LogD("onDismissScreen invoked");
InterfaceAds.onAdsResult(mAdapter, InterfaceAds.RESULT_CODE_FullScreenViewDismissed, "Full screen ads view dismissed!");
AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_FullScreenViewDismissed, "Full screen ads view dismissed!");
}
@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
int errorNo = InterfaceAds.RESULT_CODE_UnknownError;
int errorNo = AdsWrapper.RESULT_CODE_UnknownError;
String errorMsg = "Unknow error";
switch (arg1) {
case NETWORK_ERROR:
errorNo = InterfaceAds.RESULT_CODE_NetworkError;
errorNo = AdsWrapper.RESULT_CODE_NetworkError;
errorMsg = "Network error";
break;
case INVALID_REQUEST:
errorNo = InterfaceAds.RESULT_CODE_NetworkError;
errorNo = AdsWrapper.RESULT_CODE_NetworkError;
errorMsg = "The ad request is invalid";
break;
case NO_FILL:
@ -234,7 +232,7 @@ public class AdsAdmob implements AdsAdapter {
break;
}
LogD("failed to receive ad : " + errorNo + " , " + errorMsg);
InterfaceAds.onAdsResult(mAdapter, errorNo, errorMsg);
AdsWrapper.onAdsResult(mAdapter, errorNo, errorMsg);
}
@Override
@ -245,13 +243,18 @@ public class AdsAdmob implements AdsAdapter {
@Override
public void onPresentScreen(Ad arg0) {
LogD("onPresentScreen invoked");
InterfaceAds.onAdsResult(mAdapter, InterfaceAds.RESULT_CODE_FullScreenViewShown, "Full screen ads view shown!");
AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_FullScreenViewShown, "Full screen ads view shown!");
}
@Override
public void onReceiveAd(Ad arg0) {
LogD("onReceiveAd invoked");
InterfaceAds.onAdsResult(mAdapter, InterfaceAds.RESULT_CODE_AdsReceived, "Ads request received success!");
AdsWrapper.onAdsResult(mAdapter, AdsWrapper.RESULT_CODE_AdsReceived, "Ads request received success!");
}
}
@Override
public String getPluginVersion() {
return "0.2.0";
}
}

View File

@ -1,81 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCX_IAP_ALIPAY_H__
#define __CCX_IAP_ALIPAY_H__
#include "ProtocolIAP.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
class IAPAlipay : public ProtocolIAP
{
PLUGIN_REGISTER_DECL(IAPAlipay)
public:
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief config the developer info
@param devInfo This parameter is the info of developer, must contains key:
AlipayPartner The partner id of alipay account
AlipaySeller The seller id of alipay account
AlipayRsaPrivate The RSA private key of alipay account
AlipayPublic The public key of alipay account
AlipayNotifyUrl The notify url of developer (must not be empty)
AlipayPluginName The apk file name of Alipay (must not be empty)
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void configDeveloperInfo(TIAPDeveloperInfo devInfo);
/**
@brief pay for product
@param info The info of product, must contains key:
productName The name of product
productPrice The price of product(must can be parse to float)
productDesc The description of product
@warning For different plugin, the parameter should have other keys to pay.
Look at the manual of plugins.
*/
virtual void payForProduct(TProductInfo info);
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
virtual ~IAPAlipay();
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_IAP_ALIPAY_H__ */

View File

@ -1,60 +0,0 @@
[alipay]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = pluginx_alipay
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = plugin
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include/linux -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include -I%(androidndkdir)s/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.6/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
clang_flags = -nostdinc -x c++
cocos_headers = -I%(pluginxdir)s/protocols/include -I%(pluginxdir)s/plugins/alipay/include
cocos_flags = -DANDROID
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s
# what headers to parse
headers = %(pluginxdir)s/plugins/alipay/include/IAPAlipay.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^CCMenu*$".
classes = IAPAlipay
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = *::[createPlugin]
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# CCSet is special and we will use a hand-written constructor
abstract_classes = IAPAlipay
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

View File

@ -1,84 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "IAPAlipay.h"
#include "PluginUtils.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(IAPAlipay)
IAPAlipay::~IAPAlipay()
{
}
/**
@brief plugin initialization
*/
bool IAPAlipay::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.IAPAlipay");
}
/**
@brief config the developer info
@param devInfo This parameter is the info of developer, must contains key:
AlipayPartner The partner id of alipay account
AlipaySeller The seller id of alipay account
AlipayRsaPrivate The RSA private key of alipay account
AlipayPublic The public key of alipay account
AlipayNotifyUrl The notify url of developer (must not be empty)
AlipayPluginName The apk file name of Alipay (must not be empty)
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
void IAPAlipay::configDeveloperInfo(TIAPDeveloperInfo devInfo)
{
ProtocolIAP::configDeveloperInfo(devInfo);
}
/**
@brief pay for product
@param info The info of product, must contains key:
productName The name of product
productPrice The price of product(must can be parse to float)
productDesc The description of product
@warning For different plugin, the parameter should have other keys to pay.
Look at the manual of plugins.
*/
void IAPAlipay::payForProduct(TProductInfo info)
{
ProtocolIAP::payForProduct(info);
}
const char* IAPAlipay::getSDKVersion()
{
return ProtocolIAP::getSDKVersion();
}
void IAPAlipay::setDebugMode(bool debug)
{
ProtocolIAP::setDebugMode(debug);
}
}} // namespace cocos2d { namespace plugin {

View File

@ -30,16 +30,4 @@
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,20 +0,0 @@
# set params
PLUGIN_ANDROID_ROOT=$(cd "$(dirname "$0")"; pwd)
if [ ! "${PLUGIN_ROOT}" ]; then
PLUGIN_ROOT="$PLUGIN_ANDROID_ROOT"/../..
fi
# build
"$ANDROID_NDK_ROOT"/ndk-build -C "$PLUGIN_ANDROID_ROOT" \
NDK_MODULE_PATH="$PLUGIN_ROOT"
echo
if [ "0" != "$?" ]; then
echo "Build error occoured!!!"
exit 1
fi
echo
echo "Native build action success."
exit 0

View File

@ -1,29 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PluginAlipayStatic
LOCAL_MODULE_FILENAME := libPluginAlipayStatic
LOCAL_SRC_FILES := \
$(addprefix ../../platform/android/, \
IAPAlipay.cpp \
) \
LOCAL_CFLAGS :=
LOCAL_EXPORT_CFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module, protocols/proj.android/jni)

View File

@ -1,7 +0,0 @@
# it is needed for ndk-r5
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_MODULES := PluginAlipayStatic
APP_ABI :=armeabi
#APP_ABI :=x86
#APP_ABI :=mips mips-r2 mips-r2-sf armeabi

View File

@ -28,8 +28,6 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import org.cocos2dx.plugin.InterfaceIAP.IAPAdapter;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
@ -41,7 +39,7 @@ import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
public class IAPAlipay implements IAPAdapter {
public class IAPAlipay implements InterfaceIAP {
private static final String LOG_TAG = "IAPAlipay";
private static Activity mContext = null;
@ -97,7 +95,7 @@ public class IAPAlipay implements IAPAdapter {
public void payForProduct(Hashtable<String, String> info) {
LogD("payForProduct invoked " + info.toString());
if (! networkReachable()) {
payResult(InterfaceIAP.PAYRESULT_FAIL, "网络不可用");
payResult(IAPWrapper.PAYRESULT_FAIL, "网络不可用");
return;
}
@ -108,7 +106,7 @@ public class IAPAlipay implements IAPAdapter {
MobileSecurePayHelper mspHelper = new MobileSecurePayHelper(mContext);
boolean bInstalled = mspHelper.detectMobile_sp();
if (! bInstalled) {
payResult(InterfaceIAP.PAYRESULT_FAIL, "未安装支付宝插件");
payResult(IAPWrapper.PAYRESULT_FAIL, "未安装支付宝插件");
return;
}
@ -138,12 +136,12 @@ public class IAPAlipay implements IAPAdapter {
closeProgress();
mProgress = BaseHelper.showProgress(mContext, null, "正在支付", false, true);
} else {
payResult(InterfaceIAP.PAYRESULT_FAIL, "支付失败");
payResult(IAPWrapper.PAYRESULT_FAIL, "支付失败");
return;
}
} catch (Exception ex) {
LogE("Remote call failed", ex);
payResult(InterfaceIAP.PAYRESULT_FAIL, "remote call failed");
payResult(IAPWrapper.PAYRESULT_FAIL, "remote call failed");
return;
}
}
@ -200,21 +198,21 @@ public class IAPAlipay implements IAPAdapter {
int retVal = resultChecker.checkSign();
// 返回验签结果以及交易状态
if (retVal == ResultChecker.RESULT_CHECK_SIGN_FAILED) {
payResult(InterfaceIAP.PAYRESULT_FAIL, "签名验证失败");
payResult(IAPWrapper.PAYRESULT_FAIL, "签名验证失败");
} else if (retVal == ResultChecker.RESULT_CHECK_SIGN_SUCCEED && resultChecker.isPayOk()) {
payResult(InterfaceIAP.PAYRESULT_SUCCESS, "支付成功");
payResult(IAPWrapper.PAYRESULT_SUCCESS, "支付成功");
} else {
payResult(InterfaceIAP.PAYRESULT_FAIL, "支付失败");
payResult(IAPWrapper.PAYRESULT_FAIL, "支付失败");
}
} catch (Exception e) {
e.printStackTrace();
payResult(InterfaceIAP.PAYRESULT_FAIL, "结果解析失败");
payResult(IAPWrapper.PAYRESULT_FAIL, "结果解析失败");
}
}
break;
default:
mAdapter.closeProgress();
payResult(InterfaceIAP.PAYRESULT_FAIL, "支付失败");
payResult(IAPWrapper.PAYRESULT_FAIL, "支付失败");
break;
}
@ -335,7 +333,12 @@ public class IAPAlipay implements IAPAdapter {
}
private static void payResult(int ret, String msg) {
InterfaceIAP.onPayResult(mAdapter, ret, msg);
IAPWrapper.onPayResult(mAdapter, ret, msg);
LogD("Alipay result : " + ret + " msg : " + msg);
}
@Override
public String getPluginVersion() {
return "0.2.0";
}
}

View File

@ -1,170 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCX_ANALYTICS_FLURRY_H__
#define __CCX_ANALYTICS_FLURRY_H__
#include "ProtocolAnalytics.h"
namespace cocos2d { namespace plugin {
class AnalyticsFlurry : public ProtocolAnalytics
{
PLUGIN_REGISTER_DECL(AnalyticsFlurry)
public:
enum Gender{
FEMALE = 0,
MALE = 1
};
virtual ~AnalyticsFlurry();
/**
@par override interface of base class
*/
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief Start a new session.
@param appKey The identity of the application.
*/
virtual void startSession(const char* appKey);
/**
@brief Stop a session.
@warning This interface only worked on android
*/
virtual void stopSession();
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
@note It must be invoked before calling startSession.
*/
virtual void setDebugMode(bool debug);
/**
@brief Set the timeout for expiring a session.
@param millis In milliseconds as the unit of time.
@note It must be invoked before calling startSession.
*/
virtual void setSessionContinueMillis(long millis);
/**
@brief log an error
@param errorId The identity of error
@param message Extern message for the error
*/
virtual void logError(const char* errorId, const char* message);
/**
@brief log an event.
@param eventId The identity of event
@param paramMap Extern parameters of the event, use NULL if not needed.
*/
virtual void logEvent(const char* eventId, LogEventParamMap* paramMap = NULL);
/**
@brief Track an event begin.
@param eventId The identity of event
*/
virtual void logTimedEventBegin(const char* eventId);
/**
@brief Track an event end.
@param eventId The identity of event
*/
virtual void logTimedEventEnd(const char* eventId);
/**
@brief Whether to catch uncaught exceptions to server.
@warning This interface only worked on android.
*/
virtual void setCaptureUncaughtException(bool enabled);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
/**
@par Unique interface of Flurry
*/
/**
@brief Sets the age of the user at the time of this session.
*/
void setAge(int age);
/**
@brief Sets the gender of the user.
*/
void setGender(Gender gender);
/**
@brief Sets the userId for this session.
*/
void setUserId(const char* userId);
/**
@brief Log a page view.
*/
void logPageView();
/**
@brief Set the version name of the app.
@note It must be invoked before calling startSession.
*/
void setVersionName(const char* versionName);
/**
@par interface for android
*/
/**
@brief Enable the use of HTTPS communications.
@warning This interface only worked on android
*/
void setUseHttps(bool useHttps);
/** @brief Enable or disable detailed location reporting.
* @note It must be invoked before calling startSession.
* @warning This interface only worked on android
*/
void setReportLocation(bool enabled);
/**
@par interface for ios
*/
/**
@brief Log a timed event with parameters.
@warning The paramMap is only worked on ios.
On android, paramMap is ignored.
*/
void logTimedEventBegin(const char* eventId, LogEventParamMap* paramMap);
void logTimedEventEnd(const char* eventId, LogEventParamMap* paramMap);
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_ANALYTICS_FLURRY_H__ */

View File

@ -1,59 +0,0 @@
[flurry]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = pluginx_flurry
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = plugin
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include/linux -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include -I%(androidndkdir)s/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.6/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
clang_flags = -nostdinc -x c++
cocos_headers = -I%(pluginxdir)s/protocols/include -I%(pluginxdir)s/plugins/flurry/include
cocos_flags = -DANDROID
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s
# what headers to parse
headers = %(pluginxdir)s/plugins/flurry/include/AnalyticsFlurry.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^CCMenu*$".
classes = AnalyticsFlurry
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = *::[createPlugin]
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# CCSet is special and we will use a hand-written constructor
abstract_classes = AnalyticsFlurry
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

View File

@ -1,246 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "AnalyticsFlurry.h"
#include "PluginJniHelper.h"
#include <android/log.h>
#include "PluginUtils.h"
#include "PluginJavaData.h"
#if 1
#define LOG_TAG "AnalyticsFlurry"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(AnalyticsFlurry)
AnalyticsFlurry::~AnalyticsFlurry()
{
LOGD("AnalyticsFlurry destructor");
}
bool AnalyticsFlurry::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.AnalyticsFlurry");
}
void AnalyticsFlurry::setReportLocation(bool enabled)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setReportLocation"
, "(Z)V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, enabled);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::logPageView()
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "logPageView"
, "()V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::setVersionName(const char* versionName)
{
return_if_fails(versionName != NULL && strlen(versionName) > 0);
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setVersionName"
, "(Ljava/lang/String;)V"))
{
jstring jversionName = t.env->NewStringUTF(versionName);
t.env->CallVoidMethod(pData->jobj, t.methodID, jversionName);
t.env->DeleteLocalRef(jversionName);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::setAge(int age)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setAge"
, "(I)V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, age);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::setGender(Gender gender)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setGender"
, "(B)V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, (jbyte)gender);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::setUserId(const char* userId)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
return_if_fails(userId != NULL && strlen(userId) > 0);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setUserId"
, "(Ljava/lang/String;)V"))
{
jstring juserId = t.env->NewStringUTF(userId);
t.env->CallVoidMethod(pData->jobj, t.methodID, juserId);
t.env->DeleteLocalRef(juserId);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::setUseHttps(bool useHttps)
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "setUseHttps"
, "(Z)V"))
{
t.env->CallVoidMethod(pData->jobj, t.methodID, useHttps);
t.env->DeleteLocalRef(t.classID);
}
}
void AnalyticsFlurry::logTimedEventBegin(const char* eventId)
{
ProtocolAnalytics::logTimedEventBegin(eventId);
}
void AnalyticsFlurry::logTimedEventBegin(const char* eventId, LogEventParamMap* paramMap)
{
return_if_fails(eventId != NULL && strlen(eventId) > 0);
if (paramMap == NULL)
{
ProtocolAnalytics::logTimedEventBegin(eventId);
}
else
{
PluginJavaData* pData = PluginUtils::getPluginJavaData(this);
PluginJniMethodInfo t;
if (PluginJniHelper::getMethodInfo(t
, pData->jclassName.c_str()
, "logTimedEventBegin"
, "(Ljava/lang/String;Ljava/util/Hashtable;)V"))
{
jstring jeventId = t.env->NewStringUTF(eventId);
jobject jparamMap= PluginUtils::createJavaMapObject(t, paramMap);
t.env->CallVoidMethod(pData->jobj, t.methodID, jeventId, jparamMap);
t.env->DeleteLocalRef(jeventId);
t.env->DeleteLocalRef(jparamMap);
t.env->DeleteLocalRef(t.classID);
}
}
}
/** override methods of base class */
/** Start a new session. */
void AnalyticsFlurry::startSession(const char* appKey)
{
ProtocolAnalytics::startSession(appKey);
}
/** Stop a session. */
void AnalyticsFlurry::stopSession()
{
ProtocolAnalytics::stopSession();
}
/** Set the timeout for expiring a session. */
void AnalyticsFlurry::setSessionContinueMillis(long millis)
{
ProtocolAnalytics::setSessionContinueMillis(millis);
}
/** Whether to catch uncaught exceptions to server.*/
void AnalyticsFlurry::setCaptureUncaughtException(bool enabled)
{
ProtocolAnalytics::setCaptureUncaughtException(enabled);
}
const char* AnalyticsFlurry::getSDKVersion()
{
return ProtocolAnalytics::getSDKVersion();
}
/** Set whether needs to output logs to console.*/
void AnalyticsFlurry::setDebugMode(bool debug)
{
ProtocolAnalytics::setDebugMode(debug);
}
/** log an error */
void AnalyticsFlurry::logError(const char* errorId, const char* message)
{
ProtocolAnalytics::logError(errorId, message);
}
/** log an event. */
void AnalyticsFlurry::logEvent(const char* eventId, LogEventParamMap* paramMap)
{
ProtocolAnalytics::logEvent(eventId, paramMap);
}
/** end a timed event */
void AnalyticsFlurry::logTimedEventEnd(const char* eventId)
{
ProtocolAnalytics::logTimedEventEnd(eventId);
}
void AnalyticsFlurry::logTimedEventEnd(const char* eventId, LogEventParamMap* paramMap)
{
ProtocolAnalytics::logTimedEventEnd(eventId);
}
}} // namespace cocos2d { namespace plugin {

View File

@ -1,221 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "AnalyticsFlurry.h"
#include "Flurry.h"
#include "PluginUtilsIOS.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(AnalyticsFlurry)
#define LOG_MAX_LENGTH (16 * 1024)
static bool s_bDebugable = false;
void FlurryLogD(const char * pszFormat, ...)
{
if (s_bDebugable) {
printf("AnalyticsFlurry : ");
char szBuf[LOG_MAX_LENGTH];
va_list ap;
va_start(ap, pszFormat);
vsnprintf(szBuf, LOG_MAX_LENGTH, pszFormat, ap);
va_end(ap);
printf("%s", szBuf);
printf("\n");
}
}
AnalyticsFlurry::~AnalyticsFlurry()
{
}
bool AnalyticsFlurry::init()
{
return PluginUtilsIOS::initOCPlugin(this, "FlurryWrapper");
}
/** override methods of base class */
/** Start a new session. */
void AnalyticsFlurry::startSession(const char* appKey)
{
ProtocolAnalytics::startSession(appKey);
}
/** Stop a session.
only worked on android
*/
void AnalyticsFlurry::stopSession()
{
ProtocolAnalytics::stopSession();
}
/** Set whether needs to output logs to console.*/
void AnalyticsFlurry::setDebugMode(bool debug)
{
s_bDebugable = debug;
ProtocolAnalytics::setDebugMode(debug);
}
/** Set the timeout for expiring a session. */
void AnalyticsFlurry::setSessionContinueMillis(long millis)
{
ProtocolAnalytics::setSessionContinueMillis(millis);
}
/** log an error */
void AnalyticsFlurry::logError(const char* errorId, const char* message)
{
ProtocolAnalytics::logError(errorId, message);
}
/** log an event. */
void AnalyticsFlurry::logEvent(const char* eventId, LogEventParamMap* paramMap)
{
ProtocolAnalytics::logEvent(eventId, paramMap);
}
void AnalyticsFlurry::logTimedEventBegin(const char* eventId)
{
ProtocolAnalytics::logTimedEventBegin(eventId);
}
/** end a timed event */
void AnalyticsFlurry::logTimedEventEnd(const char* eventId)
{
ProtocolAnalytics::logTimedEventEnd(eventId);
}
/** Whether to catch uncaught exceptions to server.
only worked on android
*/
void AnalyticsFlurry::setCaptureUncaughtException(bool enabled)
{
ProtocolAnalytics::setCaptureUncaughtException(enabled);
}
const char* AnalyticsFlurry::getSDKVersion()
{
return ProtocolAnalytics::getSDKVersion();
}
void AnalyticsFlurry::setAge(int age)
{
NSNumber* numAge = [NSNumber numberWithInt:age];
PluginUtilsIOS::callOCFunctionWithName_Object(this, "setAge:", numAge);
}
void AnalyticsFlurry::setGender(Gender gender)
{
NSString* ret = @"m";
if (gender == FEMALE) {
ret = @"f";
}
PluginUtilsIOS::callOCFunctionWithName_Object(this, "setGender:", ret);
}
void AnalyticsFlurry::setUserId(const char* userId)
{
if (NULL == userId || strlen(userId) == 0) {
FlurryLogD("userId is invalid");
return;
}
NSString* pUserID = [NSString stringWithUTF8String:userId];
PluginUtilsIOS::callOCFunctionWithName_Object(this, "setUserId:", pUserID);
}
void AnalyticsFlurry::logPageView()
{
PluginUtilsIOS::callOCFunctionWithName(this, "logPageView");
}
void AnalyticsFlurry::setVersionName(const char* versionName)
{
NSString* pVer = [NSString stringWithUTF8String:versionName];
PluginUtilsIOS::callOCFunctionWithName_Object(this, "setVersionName:", pVer);
}
/**
@warning only worked on android
*/
void AnalyticsFlurry::setUseHttps(bool useHttps)
{
FlurryLogD("setUseHttps in flurry not available on iOS");
}
/**
@warning only worked on android
*/
void AnalyticsFlurry::setReportLocation(bool enabled)
{
FlurryLogD("setReportLocation in flurry not available on iOS");
}
void AnalyticsFlurry::logTimedEventBegin(const char* eventId, LogEventParamMap* paramMap)
{
if (NULL == eventId || strlen(eventId) == 0) {
FlurryLogD("eventId is invalid!");
return;
}
NSString* pId = [NSString stringWithUTF8String:eventId];
if (NULL == paramMap) {
this->logTimedEventBegin(eventId);
} else {
NSMutableDictionary* dict = PluginUtilsIOS::createDictFromMap(paramMap);
PluginOCData* pData = PluginUtilsIOS::getPluginOCData(this);
if (pData) {
id pOCObj = pData->obj;
SEL selector = NSSelectorFromString(@"logTimedEventBegin:withParam:");
if ([pOCObj respondsToSelector:selector]) {
[pOCObj performSelector:selector withObject:pId withObject:dict];
}
}
}
}
void AnalyticsFlurry::logTimedEventEnd(const char* eventId, LogEventParamMap* paramMap)
{
if (NULL == eventId || strlen(eventId) == 0) {
FlurryLogD("eventId is invalid!");
return;
}
NSString* pId = [NSString stringWithUTF8String:eventId];
if (NULL == paramMap) {
this->logTimedEventEnd(eventId);
} else {
NSMutableDictionary* dict = PluginUtilsIOS::createDictFromMap(paramMap);
PluginOCData* pData = PluginUtilsIOS::getPluginOCData(this);
if (pData) {
id pOCObj = pData->obj;
SEL selector = NSSelectorFromString(@"logTimedEventEnd:withParam:");
if ([pOCObj respondsToSelector:selector]) {
[pOCObj performSelector:selector withObject:pId withObject:dict];
}
}
}
}
}} // namespace cocos2d { namespace plugin {

View File

@ -1,129 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#import "FlurryWrapper.h"
#import "Flurry.h"
@implementation FlurryWrapper
- (void) startSession: (NSString*) appKey
{
[Flurry startSession:appKey];
}
- (void) stopSession
{
NSLog(@"stopSession in flurry not available on iOS");
}
- (void) setSessionContinueMillis: (NSNumber*) millis
{
long lMillis = [millis longValue];
int seconds = (int)(lMillis / 1000);
[Flurry setSessionContinueSeconds:seconds];
}
- (void) setCaptureUncaughtException: (NSNumber*) isEnabled
{
NSLog(@"setCaptureUncaughtException in flurry not available on iOS");
}
- (void) setDebugMode: (NSNumber*) isDebugMode
{
BOOL bDebug = [isDebugMode boolValue];
[Flurry setDebugLogEnabled:bDebug];
}
- (void) logError: (NSString*) errorId withMsg:(NSString*) message
{
NSString* msg = nil;
if (nil == message) {
msg = @"";
} else {
msg = message;
}
[Flurry logError:errorId message:msg exception:nil];
}
- (void) logEvent: (NSString*) eventId
{
[Flurry logEvent:eventId];
}
- (void) logEvent: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap
{
[Flurry logEvent:eventId withParameters:paramMap];
}
- (void) logTimedEventBegin: (NSString*) eventId
{
[Flurry logEvent:eventId timed:YES];
}
- (void) logTimedEventEnd: (NSString*) eventId
{
[Flurry endTimedEvent:eventId withParameters:nil];
}
- (NSString*) getSDKVersion
{
return [Flurry getFlurryAgentVersion];
}
- (void) setAge: (NSNumber*) age
{
int nAge = [age integerValue];
[Flurry setAge:nAge];
}
- (void) setGender: (NSString*) gender
{
[Flurry setGender:gender];
}
- (void) setUserId: (NSString*) userId
{
[Flurry setUserID:userId];
}
- (void) logPageView
{
[Flurry logPageView];
}
- (void) setVersionName: (NSString*) versionName
{
[Flurry setAppVersion:versionName];
}
- (void) logTimedEventBegin: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap
{
[Flurry logEvent:eventId withParameters:paramMap timed:YES];
}
- (void) logTimedEventEnd: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap
{
[Flurry endTimedEvent:eventId withParameters:paramMap];
}
@end

View File

@ -30,16 +30,4 @@
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,20 +0,0 @@
# set params
PLUGIN_ANDROID_ROOT=$(cd "$(dirname "$0")"; pwd)
if [ ! "${PLUGIN_ROOT}" ]; then
PLUGIN_ROOT="$PLUGIN_ANDROID_ROOT"/../..
fi
# build
"$ANDROID_NDK_ROOT"/ndk-build -C "$PLUGIN_ANDROID_ROOT" \
NDK_MODULE_PATH="$PLUGIN_ROOT"
echo
if [ "0" != "$?" ]; then
echo "Build error occoured!!!"
exit 1
fi
echo
echo "Native build action success."
exit 0

View File

@ -1,29 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := PluginFlurryStatic
LOCAL_MODULE_FILENAME := libPluginFlurryStatic
LOCAL_SRC_FILES := \
$(addprefix ../../platform/android/, \
AnalyticsFlurry.cpp \
) \
LOCAL_CFLAGS :=
LOCAL_EXPORT_CFLAGS :=
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
LOCAL_LDLIBS := -landroid
LOCAL_LDLIBS += -llog
include $(BUILD_STATIC_LIBRARY)
$(call import-module, protocols/proj.android/jni)

View File

@ -1,7 +0,0 @@
# it is needed for ndk-r5
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_MODULES := PluginFlurryStatic
APP_ABI :=armeabi
#APP_ABI :=x86
#APP_ABI :=mips mips-r2 mips-r2-sf armeabi

View File

@ -24,6 +24,9 @@ THE SOFTWARE.
package org.cocos2dx.plugin;
import java.util.Hashtable;
import java.util.Iterator;
import org.json.JSONObject;
import android.content.Context;
import android.util.Log;
@ -32,170 +35,191 @@ import com.flurry.android.FlurryAgent;
public class AnalyticsFlurry implements InterfaceAnalytics {
private Context mContext = null;
protected static String TAG = "AnalyticsFlurry";
protected static void LogE(String msg, Exception e) {
Log.e(TAG, msg, e);
e.printStackTrace();
}
private Context mContext = null;
protected static String TAG = "AnalyticsFlurry";
private static boolean isDebug = false;
protected static void LogD(String msg) {
if (isDebug) {
Log.d(TAG, msg);
}
}
protected static void LogE(String msg, Exception e) {
Log.e(TAG, msg, e);
e.printStackTrace();
}
public AnalyticsFlurry(Context context) {
mContext = context;
}
@Override
public void startSession(String appKey) {
LogD("startSession invoked!");
FlurryAgent.onStartSession(mContext, appKey);
}
private static boolean isDebug = false;
protected static void LogD(String msg) {
if (isDebug) {
Log.d(TAG, msg);
}
}
@Override
public void stopSession() {
LogD("stopSession invoked!");
FlurryAgent.onEndSession(mContext);
}
public AnalyticsFlurry(Context context) {
mContext = context;
}
@Override
public void startSession(String appKey) {
LogD("startSession invoked!");
FlurryAgent.onStartSession(mContext, appKey);
}
@Override
public void setSessionContinueMillis(int millis) {
LogD("setSessionContinueMillis invoked!");
FlurryAgent.setContinueSessionMillis(millis);
}
@Override
public void stopSession() {
LogD("stopSession invoked!");
FlurryAgent.onEndSession(mContext);
}
@Override
public void setCaptureUncaughtException(boolean isEnabled) {
LogD("setCaptureUncaughtException invoked!");
FlurryAgent.setCaptureUncaughtExceptions(isEnabled);
}
@Override
public void setSessionContinueMillis(int millis) {
LogD("setSessionContinueMillis invoked!");
FlurryAgent.setContinueSessionMillis(millis);
}
@Override
public void setDebugMode(boolean isDebugMode) {
isDebug = isDebugMode;
FlurryAgent.setLogEnabled(isDebug);
if (isDebugMode) {
FlurryAgent.setLogLevel(Log.DEBUG);
}
}
@Override
public void setCaptureUncaughtException(boolean isEnabled) {
LogD("setCaptureUncaughtException invoked!");
FlurryAgent.setCaptureUncaughtExceptions(isEnabled);
}
@Override
public void logError(String errorId, String message) {
LogD("logError invoked!");
FlurryAgent.onError(errorId, message, "");
}
@Override
public void setDebugMode(boolean isDebugMode) {
isDebug = isDebugMode;
FlurryAgent.setLogEnabled(isDebug);
if (isDebugMode) {
FlurryAgent.setLogLevel(Log.DEBUG);
}
}
@Override
public void logEvent(String eventId) {
LogD("logEvent(eventId) invoked!");
FlurryAgent.logEvent(eventId);
}
@Override
public void logError(String errorId, String message) {
LogD("logError invoked!");
FlurryAgent.onError(errorId, message, "");
}
@Override
public void logEvent(String eventId, Hashtable<String, String> paramMap) {
LogD("logEvent(eventId, paramMap) invoked!");
FlurryAgent.logEvent(eventId, paramMap);
}
@Override
public void logEvent(String eventId) {
LogD("logEvent(eventId) invoked!");
FlurryAgent.logEvent(eventId);
}
@Override
public void logTimedEventBegin(String eventId) {
LogD("logTimedEventBegin invoked!");
FlurryAgent.logEvent(eventId, true);
}
@Override
public void logEvent(String eventId, Hashtable<String, String> paramMap) {
LogD("logEvent(eventId, paramMap) invoked!");
FlurryAgent.logEvent(eventId, paramMap);
}
@Override
public void logTimedEventEnd(String eventId) {
LogD("logTimedEventEnd invoked!");
FlurryAgent.endTimedEvent(eventId);
}
@Override
public void logTimedEventBegin(String eventId) {
LogD("logTimedEventBegin invoked!");
FlurryAgent.logEvent(eventId, true);
}
@Override
public String getSDKVersion() {
LogD("getSDKVersion invoked!");
String ret = "";
try {
int nRet = FlurryAgent.getAgentVersion();
ret = "Flurry android ver " + nRet;
} catch(Exception e){
LogE("Exception in getSDKVersion", e);
}
return ret;
}
@Override
public void logTimedEventEnd(String eventId) {
LogD("logTimedEventEnd invoked!");
FlurryAgent.endTimedEvent(eventId);
}
protected void logTimedEventBegin(String eventId, Hashtable<String, String> paramMap) {
LogD("logTimedEventBegin invoked!");
try{
FlurryAgent.logEvent(eventId, paramMap, true);
} catch(Exception e){
LogE("Exception in logTimedEventBegin", e);
}
}
protected void setReportLocation(boolean enabled) {
LogD("setReportLocation invoked!");
try{
FlurryAgent.setReportLocation(enabled);
} catch(Exception e){
LogE("Exception in setReportLocation", e);
}
}
protected void logPageView() {
LogD("logPageView invoked!");
try{
FlurryAgent.onPageView();
} catch(Exception e){
LogE("Exception in logPageView", e);
}
}
@Override
public String getSDKVersion() {
LogD("getSDKVersion invoked!");
String ret = "";
try {
int nRet = FlurryAgent.getAgentVersion();
ret = "Flurry android ver " + nRet;
} catch(Exception e){
LogE("Exception in getSDKVersion", e);
}
return ret;
}
protected void setVersionName(String versionName) {
LogD("setVersionName invoked!");
try {
FlurryAgent.setVersionName(versionName);
} catch(Exception e){
LogE("Exception in setVersionName", e);
}
}
protected void setAge(int age) {
LogD("setAge invoked!");
try {
FlurryAgent.setAge(age);
} catch(Exception e){
LogE("Exception in setAge", e);
}
}
protected void setGender(byte gender) {
LogD("setGender invoked!");
try {
FlurryAgent.setGender(gender);
} catch(Exception e){
LogE("Exception in setGender", e);
}
}
protected void setUserId(String userId) {
LogD("setUserId invoked!");
try {
FlurryAgent.setUserId(userId);
} catch(Exception e){
LogE("Exception in setUserId", e);
}
}
protected void setUseHttps(boolean useHttps) {
LogD("setUseHttps invoked!");
try {
FlurryAgent.setUseHttps(useHttps);
} catch(Exception e){
LogE("Exception in setUseHttps", e);
}
}
protected void logTimedEventBeginWithParams(JSONObject eventInfo) {
LogD("logTimedEventBegin invoked!");
try{
String eventId = eventInfo.getString("Param1");
if (eventInfo.has("Param2"))
{
JSONObject params = eventInfo.getJSONObject("Param2");
@SuppressWarnings("rawtypes")
Iterator it = params.keys();
Hashtable<String, String> paramMap = new Hashtable<String, String>();
while (it.hasNext()) {
String key = (String) it.next();
String value = params.getString(key);
paramMap.put(key, value);
}
FlurryAgent.logEvent(eventId, paramMap, true);
} else {
FlurryAgent.logEvent(eventId, true);
}
} catch(Exception e){
LogE("Exception in logTimedEventBegin", e);
}
}
protected void setReportLocation(boolean enabled) {
LogD("setReportLocation invoked!");
try{
FlurryAgent.setReportLocation(enabled);
} catch(Exception e){
LogE("Exception in setReportLocation", e);
}
}
protected void logPageView() {
LogD("logPageView invoked!");
try{
FlurryAgent.onPageView();
} catch(Exception e){
LogE("Exception in logPageView", e);
}
}
protected void setVersionName(String versionName) {
LogD("setVersionName invoked!");
try {
FlurryAgent.setVersionName(versionName);
} catch(Exception e){
LogE("Exception in setVersionName", e);
}
}
protected void setAge(int age) {
LogD("setAge invoked!");
try {
FlurryAgent.setAge(age);
} catch(Exception e){
LogE("Exception in setAge", e);
}
}
protected void setGender(byte gender) {
LogD("setGender invoked!");
try {
FlurryAgent.setGender(gender);
} catch(Exception e){
LogE("Exception in setGender", e);
}
}
protected void setUserId(String userId) {
LogD("setUserId invoked!");
try {
FlurryAgent.setUserId(userId);
} catch(Exception e){
LogE("Exception in setUserId", e);
}
}
protected void setUseHttps(boolean useHttps) {
LogD("setUseHttps invoked!");
try {
FlurryAgent.setUseHttps(useHttps);
} catch(Exception e){
LogE("Exception in setUseHttps", e);
}
}
@Override
public String getPluginVersion() {
return "0.2.0";
}
}

View File

@ -23,25 +23,28 @@ THE SOFTWARE.
****************************************************************************/
#import "InterfaceAnalytics.h"
@interface FlurryWrapper : NSObject <InterfaceAnalytics>
@interface AnalyticsFlurry : NSObject <InterfaceAnalytics>
{
}
@property BOOL debug;
/**
interfaces of protocol : InterfaceAnalytics
*/
- (void) startSession: (NSString*) appKey;
- (void) stopSession;
- (void) setSessionContinueMillis: (NSNumber*) millis;
- (void) setCaptureUncaughtException: (NSNumber*) isEnabled;
- (void) setDebugMode: (NSNumber*) isDebugMode;
- (void) setSessionContinueMillis: (long) millis;
- (void) setCaptureUncaughtException: (BOOL) isEnabled;
- (void) setDebugMode: (BOOL) isDebugMode;
- (void) logError: (NSString*) errorId withMsg:(NSString*) message;
- (void) logEvent: (NSString*) eventId;
- (void) logEvent: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap;
- (void) logTimedEventBegin: (NSString*) eventId;
- (void) logTimedEventEnd: (NSString*) eventId;
- (NSString*) getSDKVersion;
- (NSString*) getPluginVersion;
/**
interfaces of flurry SDK
@ -49,9 +52,10 @@ THE SOFTWARE.
- (void) setAge: (NSNumber*) age;
- (void) setGender: (NSString*) gender;
- (void) setUserId: (NSString*) userId;
- (void) setUseHttps: (NSNumber*) enabled;
- (void) logPageView;
- (void) setVersionName: (NSString*) versionName;
- (void) logTimedEventBegin: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap;
- (void) logTimedEventEnd: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap;
- (void) logTimedEventBeginWithParams: (NSMutableDictionary*) params;
- (void) logTimedEventEndWithParams: (NSMutableDictionary*) params;
@end

View File

@ -0,0 +1,166 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#import "AnalyticsFlurry.h"
#import "Flurry.h"
#define OUTPUT_LOG(...) if (self.debug) NSLog(__VA_ARGS__);
@implementation AnalyticsFlurry
@synthesize debug = __debug;
- (void) startSession: (NSString*) appKey
{
[Flurry startSession:appKey];
}
- (void) stopSession
{
OUTPUT_LOG(@"Flurry stopSession in flurry not available on iOS");
}
- (void) setSessionContinueMillis: (long) millis
{
OUTPUT_LOG(@"Flurry setSessionContinueMillis invoked(%ld)", millis);
int seconds = (int)(millis / 1000);
[Flurry setSessionContinueSeconds:seconds];
}
- (void) setCaptureUncaughtException: (BOOL) isEnabled
{
OUTPUT_LOG(@"Flurry setCaptureUncaughtException in flurry not available on iOS");
}
- (void) setDebugMode: (BOOL) isDebugMode
{
OUTPUT_LOG(@"Flurry setDebugMode invoked(%d)", isDebugMode);
self.debug = isDebugMode;
[Flurry setDebugLogEnabled:isDebugMode];
}
- (void) logError: (NSString*) errorId withMsg:(NSString*) message
{
OUTPUT_LOG(@"Flurry logError invoked(%@, %@)", errorId, message);
NSString* msg = nil;
if (nil == message) {
msg = @"";
} else {
msg = message;
}
[Flurry logError:errorId message:msg exception:nil];
}
- (void) logEvent: (NSString*) eventId
{
OUTPUT_LOG(@"Flurry logEvent invoked(%@)", eventId);
[Flurry logEvent:eventId];
}
- (void) logEvent: (NSString*) eventId withParam:(NSMutableDictionary*) paramMap
{
OUTPUT_LOG(@"Flurry logEventWithParams invoked (%@, %@)", eventId, [paramMap debugDescription]);
[Flurry logEvent:eventId withParameters:paramMap];
}
- (void) logTimedEventBegin: (NSString*) eventId
{
OUTPUT_LOG(@"Flurry logTimedEventBegin invoked (%@)", eventId);
[Flurry logEvent:eventId timed:YES];
}
- (void) logTimedEventEnd: (NSString*) eventId
{
OUTPUT_LOG(@"Flurry logTimedEventEnd invoked (%@)", eventId);
[Flurry endTimedEvent:eventId withParameters:nil];
}
- (NSString*) getSDKVersion
{
return [Flurry getFlurryAgentVersion];
}
- (NSString*) getPluginVersion
{
return @"0.2.0";
}
- (void) setAge: (NSNumber*) age
{
int nAge = [age integerValue];
OUTPUT_LOG(@"Flurry setAge invoked (%d)", nAge);
[Flurry setAge:nAge];
}
- (void) setGender: (NSString*) gender
{
OUTPUT_LOG(@"Flurry setGender invoked (%@)", gender);
[Flurry setGender:gender];
}
- (void) setUserId: (NSString*) userId
{
OUTPUT_LOG(@"Flurry setUserId invoked (%@)", userId);
[Flurry setUserID:userId];
}
- (void) setUseHttps: (NSNumber*) enabled
{
BOOL bEnabled = [enabled boolValue];
OUTPUT_LOG(@"Flurry setUseHttps invoked (%@)", enabled);
[Flurry setSecureTransportEnabled:bEnabled];
}
- (void) logPageView
{
OUTPUT_LOG(@"Flurry logPageView invoked");
[Flurry logPageView];
}
- (void) setVersionName: (NSString*) versionName
{
OUTPUT_LOG(@"Flurry setVersionName invoked (%@)", versionName);
[Flurry setAppVersion:versionName];
}
- (void) logTimedEventBeginWithParams: (NSMutableDictionary*) paramMap
{
OUTPUT_LOG(@"Flurry logTimedEventBeginWithParams invoked (%@)", [paramMap debugDescription]);
NSString* eventId = (NSString*) [paramMap objectForKey:@"Param1"];
NSMutableDictionary* params = (NSMutableDictionary*) [paramMap objectForKey:@"Param2"];
if (params) {
[Flurry logEvent:eventId withParameters:paramMap timed:YES];
} else {
[Flurry logEvent:eventId timed:YES];
}
}
- (void) logTimedEventEndWithParams: (NSMutableDictionary*) paramMap
{
OUTPUT_LOG(@"Flurry logTimedEventEndWithParams invoked (%@)", [paramMap debugDescription]);
NSString* eventId = (NSString*) [paramMap objectForKey:@"Param1"];
NSMutableDictionary* params = (NSMutableDictionary*) [paramMap objectForKey:@"Param2"];
[Flurry endTimedEvent:eventId withParameters:params];
}
@end

View File

@ -8,9 +8,8 @@
/* Begin PBXBuildFile section */
FA09A376168AFD41008C1C7B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA09A375168AFD41008C1C7B /* Foundation.framework */; };
FA09A394168B00D4008C1C7B /* AnalyticsFlurry.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA09A393168B00D4008C1C7B /* AnalyticsFlurry.mm */; };
FA866509168BE0980073E055 /* libFlurry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA866508168BE0980073E055 /* libFlurry.a */; };
FA8CC2241739EFF200464206 /* FlurryWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = FA8CC2231739EFF200464206 /* FlurryWrapper.m */; };
FAB6DFDD1756F22200C90D89 /* libFlurry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAB6DFDB1756F22200C90D89 /* libFlurry.a */; };
FAB6DFE01756F29800C90D89 /* AnalyticsFlurry.m in Sources */ = {isa = PBXBuildFile; fileRef = FAB6DFDF1756F29800C90D89 /* AnalyticsFlurry.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -28,13 +27,11 @@
/* Begin PBXFileReference section */
FA09A372168AFD41008C1C7B /* libPluginFlurry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPluginFlurry.a; sourceTree = BUILT_PRODUCTS_DIR; };
FA09A375168AFD41008C1C7B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
FA09A391168AFD79008C1C7B /* AnalyticsFlurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnalyticsFlurry.h; sourceTree = "<group>"; };
FA09A393168B00D4008C1C7B /* AnalyticsFlurry.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnalyticsFlurry.mm; sourceTree = "<group>"; };
FA866507168BE0980073E055 /* Flurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flurry.h; sourceTree = "<group>"; };
FA866508168BE0980073E055 /* libFlurry.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libFlurry.a; sourceTree = "<group>"; };
FA86650E168BE22D0073E055 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
FA8CC2221739EFF200464206 /* FlurryWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlurryWrapper.h; sourceTree = "<group>"; };
FA8CC2231739EFF200464206 /* FlurryWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FlurryWrapper.m; sourceTree = "<group>"; };
FAB6DFD81756F22200C90D89 /* Flurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flurry.h; sourceTree = "<group>"; };
FAB6DFDB1756F22200C90D89 /* libFlurry.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libFlurry.a; sourceTree = "<group>"; };
FAB6DFDE1756F29800C90D89 /* AnalyticsFlurry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnalyticsFlurry.h; sourceTree = "<group>"; };
FAB6DFDF1756F29800C90D89 /* AnalyticsFlurry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnalyticsFlurry.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -43,7 +40,7 @@
buildActionMask = 2147483647;
files = (
FA09A376168AFD41008C1C7B /* Foundation.framework in Frameworks */,
FA866509168BE0980073E055 /* libFlurry.a in Frameworks */,
FAB6DFDD1756F22200C90D89 /* libFlurry.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -53,9 +50,11 @@
FA09A367168AFD41008C1C7B = {
isa = PBXGroup;
children = (
FAB6DFDE1756F29800C90D89 /* AnalyticsFlurry.h */,
FAB6DFDF1756F29800C90D89 /* AnalyticsFlurry.m */,
FAB6DFD81756F22200C90D89 /* Flurry.h */,
FAB6DFDB1756F22200C90D89 /* libFlurry.a */,
FA86650E168BE22D0073E055 /* SystemConfiguration.framework */,
FA09A392168AFD96008C1C7B /* ios */,
FA09A390168AFD79008C1C7B /* include */,
FA09A374168AFD41008C1C7B /* Frameworks */,
FA09A373168AFD41008C1C7B /* Products */,
);
@ -77,28 +76,6 @@
name = Frameworks;
sourceTree = "<group>";
};
FA09A390168AFD79008C1C7B /* include */ = {
isa = PBXGroup;
children = (
FA09A391168AFD79008C1C7B /* AnalyticsFlurry.h */,
);
name = include;
path = ../include;
sourceTree = "<group>";
};
FA09A392168AFD96008C1C7B /* ios */ = {
isa = PBXGroup;
children = (
FA8CC2221739EFF200464206 /* FlurryWrapper.h */,
FA8CC2231739EFF200464206 /* FlurryWrapper.m */,
FA866507168BE0980073E055 /* Flurry.h */,
FA866508168BE0980073E055 /* libFlurry.a */,
FA09A393168B00D4008C1C7B /* AnalyticsFlurry.mm */,
);
name = ios;
path = ../platform/ios;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -150,8 +127,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FA09A394168B00D4008C1C7B /* AnalyticsFlurry.mm in Sources */,
FA8CC2241739EFF200464206 /* FlurryWrapper.m in Sources */,
FAB6DFE01756F29800C90D89 /* AnalyticsFlurry.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -215,6 +191,7 @@
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../platform/ios\"",
"\"$(SRCROOT)\"",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = PluginFlurry;
@ -235,6 +212,7 @@
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../platform/ios\"",
"\"$(SRCROOT)\"",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = PluginFlurry;

View File

@ -1,82 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCX_IAP_ND91_H__
#define __CCX_IAP_ND91_H__
#include "ProtocolIAP.h"
#include <map>
#include <string>
namespace cocos2d { namespace plugin {
class IAPNd91 : public ProtocolIAP
{
PLUGIN_REGISTER_DECL(IAPNd91)
public:
/**
@brief plugin initialization
*/
virtual bool init();
/**
@brief config the developer info
@param devInfo This parameter is the info of developer, must contains key:
Nd91AppId The app id of nd91
Nd91AppKey The app key of nd91
Nd91Orientation The orientation of your app(use value : portrait, landscape, auto)
default value is portrait
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
virtual void configDeveloperInfo(TIAPDeveloperInfo devInfo);
/**
@brief pay for product
@param info The info of product, must contains key:
productName The name of product
productPrice The price of product(must can be parse to float)
productDesc The description of product
Nd91ProductId The product id of product for nd91
Nd91ProductCount The product number will buy(1--10000, default value 1)
Nd91OriginalPrice The original price of product(default value is same with productPrice)
@warning For different plugin, the parameter should have other keys to pay.
Look at the manual of plugins.
*/
virtual void payForProduct(TProductInfo info);
/**
@brief Set whether needs to output logs to console.
@param debug if true debug mode enabled, or debug mode disabled.
*/
virtual void setDebugMode(bool debug);
virtual const char* getPluginVersion() { return "v0.1.01"; };
virtual const char* getSDKVersion();
virtual ~IAPNd91();
};
}} // namespace cocos2d { namespace plugin {
#endif /* __CCX_IAP_ND91_H__ */

View File

@ -1,59 +0,0 @@
[nd91]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = pluginx_nd91
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = plugin
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include/linux -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.6/include -I%(androidndkdir)s/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.6/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.1/include
clang_flags = -nostdinc -x c++
cocos_headers = -I%(pluginxdir)s/protocols/include -I%(pluginxdir)s/plugins/nd91/include
cocos_flags = -DANDROID
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s
# what headers to parse
headers = %(pluginxdir)s/plugins/nd91/include/IAPNd91.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^CCMenu*$".
classes = IAPNd91
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = *::[createPlugin]
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip =
# classes that create no constructor
# CCSet is special and we will use a hand-written constructor
abstract_classes = IAPNd91
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = yes

View File

@ -1,11 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,85 +0,0 @@
/****************************************************************************
Copyright (c) 2012-2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "IAPNd91.h"
#include "PluginUtils.h"
namespace cocos2d { namespace plugin {
PLUGIN_REGISTER_IMPL(IAPNd91)
IAPNd91::~IAPNd91()
{
}
/**
@brief plugin initialization
*/
bool IAPNd91::init()
{
return PluginUtils::initJavaPlugin(this, "org.cocos2dx.plugin.IAPNd91");
}
/**
@brief config the developer info
@param devInfo This parameter is the info of developer, must contains key:
Nd91AppId The app id of nd91
Nd91AppKey The app key of nd91
Nd91Orientation The orientation of your app(use value : portrait, landscape, auto)
default value is portrait
@warning Must invoke this interface before other interfaces.
And invoked only once.
*/
void IAPNd91::configDeveloperInfo(TIAPDeveloperInfo devInfo)
{
ProtocolIAP::configDeveloperInfo(devInfo);
}
/**
@brief pay for product
@param info The info of product, must contains key:
productName The name of product
productPrice The price of product(must can be parse to float)
productDesc The description of product
Nd91ProductId The product id of product for nd91
Nd91ProductCount The product number will buy(1--10000)
Nd91OriginalPrice The original price of product
@warning For different plugin, the parameter should have other keys to pay.
Look at the manual of plugins.
*/
void IAPNd91::payForProduct(TProductInfo info)
{
ProtocolIAP::payForProduct(info);
}
const char* IAPNd91::getSDKVersion()
{
return ProtocolIAP::getSDKVersion();
}
void IAPNd91::setDebugMode(bool debug)
{
ProtocolIAP::setDebugMode(debug);
}
}} // namespace cocos2d { namespace plugin {

View File

@ -30,16 +30,4 @@
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>android</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/platform/android</locationURI>
</link>
<link>
<name>include</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/include</locationURI>
</link>
</linkedResources>
</projectDescription>

Some files were not shown because too many files have changed in this diff Show More