Skip to content

Instantly share code, notes, and snippets.

/Brest.cpp Secret

Created January 24, 2014 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/ae8aae0c5901a68bb7f9 to your computer and use it in GitHub Desktop.
Save anonymous/ae8aae0c5901a68bb7f9 to your computer and use it in GitHub Desktop.
#include <winsock2.h>//part of Nice
#include <Windows.h>
#undef GetNextSibling
#undef GetFirstChild
///parts of nice
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <agent.h>
///parts of nice
#include "include/cef_app.h"
#include "include/cef_v8.h"
#include "Brest.h"
#include "bareboneshandler.h"
#include "MyV8Stuff.h"
// Define this, define that, define everything!
//#define TEST_SINGLE_THREADED_MESSAGE_LOOP
#define JS_BUTTON 1001
CefRefPtr<MainBindings> rnd_handler;
static GMainLoop *gloop;
static gchar *stun_addr = NULL;
static guint stun_port;
static gboolean controlling;
static gboolean exit_thread, candidate_gathering_done, negotiation_done;
NiceAgent *agent;
static guint stream_id;
#if (GLIB_MAJOR_VERSION <= 2) && (GLIB_MINOR_VERSION < 32) //Glib version check
static GCond *gather_cond, *negotiate_cond;
static GMutex *gather_mutex, *negotiate_mutex;
#else
static GCond gather_cond, negotiate_cond;
static GMutex gather_mutex, negotiate_mutex;
#endif
static const gchar *state_name[] = {"disconnected", "gathering", "connecting",
"connected", "ready", "failed"};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wClass;
CefSettings settings;
cf_handler = new BareBonesHandler();
rnd_handler = new MainBindings();
GThread *gexamplethread;
CefMainArgs main_args(hInst);
#ifdef G_OS_WIN32
WSADATA w;
WSAStartup(0x0202, &w);
#endif
ZeroMemory(&wClass,sizeof(WNDCLASSEX));
wClass.cbClsExtra=NULL;
wClass.cbSize=sizeof(WNDCLASSEX);
wClass.cbWndExtra=NULL;
wClass.hbrBackground=(HBRUSH)COLOR_WINDOW;
wClass.hCursor=LoadCursor(NULL,IDC_ARROW);
wClass.hIcon=NULL;
wClass.hIconSm=NULL;
wClass.hInstance=hInst;
wClass.lpfnWndProc=(WNDPROC)WinProc;
wClass.lpszClassName=L"Window Class";
wClass.lpszMenuName=NULL;
wClass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wClass))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
int exitCode = CefExecuteProcess(main_args, rnd_handler.get());
if (exitCode >= 0) {
return exitCode;
}
CefInitialize(main_args, settings, rnd_handler.get());
HWND hWnd=CreateWindowEx(NULL,
L"Window Class",
L"Testing Viewium",
WS_OVERLAPPEDWINDOW,
200,
200,
1280,
768,
NULL,
NULL,
hInst,
NULL);
if(!hWnd)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hWnd,nShowCmd);
g_type_init();
exit_thread = FALSE;
#if (GLIB_MAJOR_VERSION <= 2) && (GLIB_MINOR_VERSION < 32)
gexamplethread = g_thread_create(&example_thread, NULL, TRUE, NULL);
#else
gexamplethread = g_thread_new("example thread", &example_thread, NULL);
#endif
// Run the mainloop. Everything else will happen asynchronously
CefRunMessageLoop();
//Loop integration Test
/*while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
CefDoMessageLoopWork();
g_main_context_iteration(g_main_loop_get_context (gloop), FALSE);
}
return Msg.wParam;*/
///
g_thread_join (gexamplethread);
g_main_loop_unref(gloop);
exit_thread = TRUE;
#ifdef G_OS_WIN32
WSACleanup();
#endif
CefShutdown();
return EXIT_SUCCESS;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
static HWND hJSButton;
LONG btny;
switch(msg)
{
case WM_DESTROY:
{
cf_handler->m_Browser = NULL;
CefQuitMessageLoop();
PostQuitMessage(0);
return 0;
}
break;
case WM_CREATE:
{
RECT rect;
GetClientRect(hWnd, &rect);
CefWindowInfo info;
rect.bottom = rect.bottom - 100;
info.SetAsChild(hWnd, rect);
CefBrowserSettings settings;
cf_handler->m_Browser = CefBrowserHost::CreateBrowserSync(info, cf_handler.get(),
"http://localhost:4242/chattest", settings);
/*cf_handler->m_Browser = CefBrowserHost::CreateBrowserSync(info, cf_handler.get(),
"http://www.youtube.com/watch?v=MyUC_28HIvA", settings);*/
btny = rect.bottom + 25;
hJSButton = CreateWindow( L"button", L"JSButton",
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
50, btny,
100, 50,
hWnd, (HMENU) JS_BUTTON,
NULL, NULL );
}
break;
case WM_COMMAND:
{
switch(wParam)
{
case JS_BUTTON:
//jprint("JS Changing that string!");
//binding = "olaola";
//jprint(binding.c_str());
//SendtoRender("TextData", "And now its changed");
//jprint(binding);
return 0;
}
break;
}
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
static void *example_thread(void *data)
{
NiceAgent *agent;
guint stream_id;
//Create gloop
#if (GLIB_MAJOR_VERSION <= 2) && (GLIB_MINOR_VERSION < 32)
gather_cond = g_cond_new();
negotiate_cond = g_cond_new();
gather_mutex = g_mutex_new();
negotiate_mutex = g_mutex_new();
#endif
gloop = g_main_loop_new(NULL, FALSE);
// Create the nice agent
agent = nice_agent_new(g_main_loop_get_context (gloop),
NICE_COMPATIBILITY_RFC5245);
if (agent == NULL)
g_error("Failed to create agent");
//
// Set the STUN settings and controlling mode
stun_addr = "77.72.174.163";
stun_port = 3478;
controlling = 1;
g_debug("Using stun server '[%s]:%u'\n", stun_addr, stun_port);
g_object_set(G_OBJECT(agent), "stun-server", stun_addr, NULL);
g_object_set(G_OBJECT(agent), "stun-server-port", stun_port, NULL);
g_object_set(G_OBJECT(agent), "controlling-mode", controlling, NULL);
// Connect to the signals
g_signal_connect(G_OBJECT(agent), "candidate-gathering-done",
G_CALLBACK(cb_candidate_gathering_done), NULL);
g_signal_connect(G_OBJECT(agent), "new-selected-pair",
G_CALLBACK(cb_new_selected_pair), NULL);
g_signal_connect(G_OBJECT(agent), "component-state-changed",
G_CALLBACK(cb_component_state_changed), NULL);
// Create a new stream with one component
stream_id = nice_agent_add_stream(agent, 1);
if (stream_id == 0)
g_error("Failed to add stream");
nice_agent_set_stream_name (agent, stream_id, "text");
// Attach to the component to receive the data
// Without this call, candidates cannot be gathered
nice_agent_attach_recv(agent, stream_id, 1,
g_main_loop_get_context (gloop), cb_nice_recv, NULL);
// Start gathering local candidates
if (!nice_agent_gather_candidates(agent, stream_id))
jprint("Failed to start candidate gathering");
jprint("waiting for candidate-gathering-done signal...");
if (exit_thread)
goto end;
g_main_loop_run (gloop);
end:
g_object_unref(agent);
g_main_loop_quit (gloop);
exit_thread = TRUE;
return NULL;
}
void jprint(const gchar *data) {
CefRefPtr<CefBrowser> browser;
if (cf_handler.get())
browser = cf_handler->GetBrowser();
if (browser.get()) {
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
gchar *jprint = g_strdup_printf("%s%s%s", "print('", data, "');");
frame->ExecuteJavaScript(jprint,
frame->GetURL(), 0);
}
}
void SendtoRender(gchar *name, gchar *insides)
{
CefRefPtr<CefBrowser> browser;
if (cf_handler.get())
browser = cf_handler->GetBrowser();
// Create the message object.
CefRefPtr<CefProcessMessage> msg= CefProcessMessage::Create(name);
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg->GetArgumentList();
// Populate the argument values.
args->SetString(0, insides);
// Send the process message to the render process.
// Use PID_BROWSER instead when sending a message to the browser process.
browser->SendProcessMessage(PID_RENDERER, msg);
}
void SendtoBoolRender(gchar *name, gboolean insides)
{
CefRefPtr<CefBrowser> browser;
if (cf_handler.get())
browser = cf_handler->GetBrowser();
// Create the message object.
CefRefPtr<CefProcessMessage> msg= CefProcessMessage::Create(name);
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg->GetArgumentList();
// Populate the argument values.
args->SetBool(0, insides);
// Send the process message to the render process.
// Use PID_BROWSER instead when sending a message to the browser process.
browser->SendProcessMessage(PID_RENDERER, msg);
}
void SendtoBrowser(gchar *name, std::string insides)
{
//CefRefPtr<CefBrowser> browser;
// if (cf_handler.get())
CefRefPtr<CefBrowser> browser = rnd_handler->browserglobal;
// Create the message object.
CefRefPtr<CefProcessMessage> msg= CefProcessMessage::Create(name);
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg->GetArgumentList();
// Populate the argument values.
args->SetString(0, insides);
// Send the process message to the render process.
// Use PID_BROWSER instead when sending a message to the browser process.
browser->SendProcessMessage(PID_BROWSER, msg);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////NICE FUNCTIONS///////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, guint len, gchar *buf, gpointer data)
{
if (len == 1 && buf[0] == '\0')
jprint("failed while passing nicetext");
jprint(g_strdup_printf("%.*s", len, buf));
}
static void
cb_new_selected_pair(NiceAgent *agent, guint stream_id,
guint component_id, gchar *lfoundation,
gchar *rfoundation, gpointer data)
{
jprint(g_strdup_printf("SIGNAL: selected pair %s %s", lfoundation, rfoundation));
}
static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, gpointer data)
{
gchar *sdp, *sdp64;
gchar *senddata = NULL;
jprint("SIGNAL candidate gathering done");
// Candidate gathering is done. Send our local candidates on stdout
// Listen on stdin for the remote candidate list
/*printf("Enter remote data (single line, no wrapping):\n");
g_io_add_watch(io_stdin, G_IO_IN, stdin_remote_info_cb, agent);
printf("> ");
fflush (stdout);*/
// Candidate gathering is done. Send our local candidates on stdout
jprint("Copy this line to remote client:");
sdp = nice_agent_generate_local_sdp (agent);
sdp64 = g_base64_encode ((const guchar *)sdp, strlen (sdp));
senddata = g_strdup_printf("\n %s\n", sdp64);
SendtoRender("NiceData", senddata);
g_free (sdp);
g_free (sdp64);
if (senddata)
g_free(senddata);
SendtoBoolRender("listening", TRUE);
// Listen on stdin for the remote candidate list
printf("Enter remote data (single line, no wrapping):\n");
printf("> ");
fflush (stdout);
while (!exit_thread) {
//GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL);
if (NiceCand.c_str() != NULL && NiceCand != "") {
jprint(NiceCand.c_str());
gsize sdp_len;
sdp = (gchar *) g_base64_decode (NiceCand.c_str(), &sdp_len);
// Parse remote candidate list and set it on the agent
if (sdp && nice_agent_parse_remote_sdp (agent, sdp) > 0) {
g_free (sdp);
NiceCand = "";
break;
} else {
fprintf(stderr, "ERROR: failed to parse remote data\n");
jprint("ERROR: failed to parse remote data");
jprint("Enter remote data (single line, no wrapping):");
fflush (stdout);
NiceCand = "";
}
g_free (sdp);
} else if (NiceCand == "") {
#if defined(__unix__) || defined(__unix)
usleep (100000);
#else
Sleep (100);
#endif
}
}
jprint("waiting for state READY or FAILED signal...");
if (exit_thread) {
g_object_unref(agent);
g_main_loop_quit (gloop);
}
}
static void
cb_component_state_changed(NiceAgent *agent, guint stream_id, guint component_id, guint state, gpointer data)
{
jprint(g_strdup_printf("SIGNAL: state changed %d %d %s[%d]",
stream_id, component_id, state_name[state], state));
if (state == NICE_COMPONENT_STATE_READY) {
SendtoBoolRender("listening", FALSE);
NiceCandidate *local, *remote;
// Get current selected candidate pair and print IP address used
if (nice_agent_get_selected_pair (agent, stream_id, component_id,
&local, &remote)) {
jprint("got pair");
gchar ipaddr[INET6_ADDRSTRLEN];
nice_address_to_string(&local->addr, ipaddr);
jprint(g_strdup_printf("\nNegotiation complete: ([%s]:%d,",
ipaddr, nice_address_get_port(&local->addr)));
nice_address_to_string(&remote->addr, ipaddr);
jprint(g_strdup_printf(" [%s]:%d)\n", ipaddr, nice_address_get_port(&remote->addr)));
}
// Listen to stdin and send data written to it
SendtoBoolRender("textlistening", TRUE);
jprint("Send lines to remote (Ctrl-D to quit):");
fflush (stdout);
while (!exit_thread) {
if (NiceText != "") {
nice_agent_send(agent, stream_id, 1, strlen(NiceText.c_str()), NiceText.c_str());
fflush (stdout);
NiceText = "";
} else if (NiceText == "") {
#if defined(__unix__) || defined(__unix)
usleep (100000);
#else
Sleep (100);
#endif
}
}
} else if (state == NICE_COMPONENT_STATE_FAILED) {
jprint("Negotiation Something failed");
g_main_loop_quit (gloop);
}
}
#ifndef BREST_H_
#define BREST_H_
#include "bareboneshandler.h"
CefRefPtr<BareBonesHandler> cf_handler;
std::string binding = "Yet not changed";
std::string NiceData;
void jprint(const gchar *data);
void SendtoRender(gchar *name, gchar *insides);
void SendtoBoolRender(gchar *name, gboolean insides);
void SendtoBrowser(gchar *name, std::string insides);
gboolean listening;
gboolean textlistening; ///BEWARE those are globals and can affect another browser windows, if there's any!
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
static void * example_thread(void *data);
static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id,
gpointer data);
static void cb_new_selected_pair(NiceAgent *agent, guint stream_id,
guint component_id, gchar *lfoundation,
gchar *rfoundation, gpointer data);
static void cb_component_state_changed(NiceAgent *agent, guint stream_id,
guint component_id, guint state,
gpointer data);
static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id,
guint len, gchar *buf, gpointer data);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment