First go at implementing rooms. A test passes that appears to exercise them.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4017 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
128
src/ssb.js.c
128
src/ssb.js.c
@ -253,6 +253,15 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_getConnection(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
const char* id = JS_ToCString(context, argv[0]);
|
||||
tf_ssb_connection_t* connection = tf_ssb_connection_get(ssb, id);
|
||||
JS_FreeCString(context, id);
|
||||
return JS_DupValue(context, tf_ssb_connection_get_object(connection));
|
||||
}
|
||||
|
||||
typedef struct _sqlStream_callback_t
|
||||
{
|
||||
JSContext* context;
|
||||
@ -319,7 +328,7 @@ typedef struct _broadcasts_t
|
||||
int length;
|
||||
} broadcasts_t;
|
||||
|
||||
static void _tf_ssb_broadcasts_visit(const struct sockaddr_in* addr, const uint8_t* pub, void* user_data)
|
||||
static void _tf_ssb_broadcasts_visit(const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data)
|
||||
{
|
||||
broadcasts_t* broadcasts = user_data;
|
||||
JSValue entry = JS_NewObject(broadcasts->context);
|
||||
@ -327,8 +336,15 @@ static void _tf_ssb_broadcasts_visit(const struct sockaddr_in* addr, const uint8
|
||||
char pubkey[k_id_base64_len];
|
||||
uv_ip4_name(addr, address, sizeof(address));
|
||||
tf_ssb_id_bin_to_str(pubkey, sizeof(pubkey), pub);
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "address", JS_NewString(broadcasts->context, address));
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "port", JS_NewInt32(broadcasts->context, ntohs(addr->sin_port)));
|
||||
if (tunnel)
|
||||
{
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "tunnel", JS_DupValue(broadcasts->context, tf_ssb_connection_get_object(tunnel)));
|
||||
}
|
||||
else
|
||||
{
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "address", JS_NewString(broadcasts->context, address));
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "port", JS_NewInt32(broadcasts->context, ntohs(addr->sin_port)));
|
||||
}
|
||||
JS_SetPropertyStr(broadcasts->context, entry, "pubkey", JS_NewString(broadcasts->context, pubkey));
|
||||
JS_SetPropertyUint32(broadcasts->context, broadcasts->array, broadcasts->length++, entry);
|
||||
}
|
||||
@ -411,6 +427,7 @@ static JSValue _tf_ssb_rpc_send_json(JSContext* context, JSValueConst this_val,
|
||||
(const uint8_t*)message,
|
||||
size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
JS_FreeValue(context, connection_val);
|
||||
JS_FreeCString(context, message);
|
||||
@ -443,6 +460,7 @@ static JSValue _tf_ssb_rpc_send_json_end(JSContext* context, JSValueConst this_v
|
||||
(const uint8_t*)message,
|
||||
size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
JS_FreeValue(context, connection_val);
|
||||
JS_FreeCString(context, message);
|
||||
@ -450,6 +468,12 @@ static JSValue _tf_ssb_rpc_send_json_end(JSContext* context, JSValueConst this_v
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static void _tf_ssb_cleanup_value(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
|
||||
JS_FreeValue(tf_ssb_get_context(ssb), callback);
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_rpc_more(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
|
||||
@ -459,7 +483,7 @@ static JSValue _tf_ssb_rpc_more(JSContext* context, JSValueConst this_val, int a
|
||||
JS_ToInt32(context, &request_number, request_val);
|
||||
JS_FreeValue(context, request_val);
|
||||
|
||||
tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_on_rpc, JS_VALUE_GET_PTR(JS_DupValue(context, argv[0])));
|
||||
tf_ssb_connection_add_request(connection, -request_number, _tf_ssb_on_rpc, _tf_ssb_cleanup_value, JS_VALUE_GET_PTR(JS_DupValue(context, argv[0])));
|
||||
|
||||
JS_FreeValue(context, connection_val);
|
||||
return JS_UNDEFINED;
|
||||
@ -485,6 +509,7 @@ static JSValue _tf_ssb_rpc_send_binary(JSContext* context, JSValueConst this_val
|
||||
(const uint8_t*)message,
|
||||
size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
@ -505,6 +530,7 @@ static JSValue _tf_ssb_rpc_send_binary(JSContext* context, JSValueConst this_val
|
||||
(const uint8_t*)message + offset,
|
||||
size,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
@ -514,6 +540,28 @@ static JSValue _tf_ssb_rpc_send_binary(JSContext* context, JSValueConst this_val
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_rpc_add_room_attendant(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
|
||||
tf_ssb_connection_t* connection = JS_GetOpaque(connection_val, tf_ssb_get_connection_class_id());
|
||||
const char* id = JS_ToCString(context, argv[0]);
|
||||
tf_ssb_connection_add_room_attendant(connection, id);
|
||||
JS_FreeCString(context, id);
|
||||
JS_FreeValue(context, connection_val);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_rpc_remove_room_attendant(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
JSValue connection_val = JS_GetPropertyStr(context, this_val, "connection");
|
||||
tf_ssb_connection_t* connection = JS_GetOpaque(connection_val, tf_ssb_get_connection_class_id());
|
||||
const char* id = JS_ToCString(context, argv[0]);
|
||||
tf_ssb_connection_remove_room_attendant(connection, id);
|
||||
JS_FreeCString(context, id);
|
||||
JS_FreeValue(context, connection_val);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
tf_ssb_t* ssb = tf_ssb_connection_get_ssb(connection);
|
||||
@ -530,6 +578,8 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ
|
||||
JS_SetPropertyStr(context, object, "send_binary", JS_NewCFunction(context, _tf_ssb_rpc_send_binary, "send_binary", 1));
|
||||
JS_SetPropertyStr(context, object, "send_json_end", JS_NewCFunction(context, _tf_ssb_rpc_send_json_end, "send_json_end", 1));
|
||||
JS_SetPropertyStr(context, object, "more", JS_NewCFunction(context, _tf_ssb_rpc_more, "more", 1));
|
||||
JS_SetPropertyStr(context, object, "add_room_attendant", JS_NewCFunction(context, _tf_ssb_rpc_add_room_attendant, "add_room_attendant", 1));
|
||||
JS_SetPropertyStr(context, object, "remove_room_attendant", JS_NewCFunction(context, _tf_ssb_rpc_remove_room_attendant, "remove_room_attendant", 1));
|
||||
|
||||
JSValue result = JS_Call(context, callback, JS_UNDEFINED, 1, &object);
|
||||
tf_util_report_error(context, result);
|
||||
@ -537,12 +587,6 @@ void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t requ
|
||||
JS_FreeValue(context, object);
|
||||
}
|
||||
|
||||
static void _tf_ssb_cleanup_value(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
JSValue callback = JS_MKPTR(JS_TAG_OBJECT, user_data);
|
||||
JS_FreeValue(tf_ssb_get_context(ssb), callback);
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_add_rpc(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
@ -888,6 +932,67 @@ static JSValue _tf_ssb_hmacsha256_verify(JSContext* context, JSValueConst this_v
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_createTunnel(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_connection_t* connection = JS_GetOpaque(argv[0], tf_ssb_get_connection_class_id());
|
||||
int32_t request_number = 0;
|
||||
JS_ToInt32(context, &request_number, argv[1]);
|
||||
const char* target_id = JS_ToCString(context, argv[2]);
|
||||
tf_ssb_connection_tunnel_create(connection, request_number, target_id);
|
||||
JS_FreeCString(context, target_id);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
typedef struct tunnel_t
|
||||
{
|
||||
tf_ssb_connection_t* connection;
|
||||
int32_t request_number;
|
||||
} tunnel_t;
|
||||
|
||||
void _tf_ssb_tunnel_rpc_callback(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data)
|
||||
{
|
||||
tunnel_t* tun = user_data;
|
||||
tf_ssb_connection_rpc_send(tun->connection, flags, tun->request_number, message, size, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void _tf_ssb_tunnel_cleanup(tf_ssb_t* ssb, void* user_data)
|
||||
{
|
||||
tf_free(user_data);
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_tunnel(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_connection_t* connection0 = JS_GetOpaque(argv[0], tf_ssb_get_connection_class_id());
|
||||
int32_t request_number0 = 0;
|
||||
JS_ToInt32(context, &request_number0, argv[1]);
|
||||
|
||||
tf_ssb_connection_t* connection1 = JS_GetOpaque(argv[2], tf_ssb_get_connection_class_id());
|
||||
int32_t request_number1 = 0;
|
||||
JS_ToInt32(context, &request_number1, argv[3]);
|
||||
|
||||
printf("TUNNEL %p %d <=> %p %d\n", connection0, request_number0, connection1, request_number1);
|
||||
|
||||
tunnel_t* data0 = tf_malloc(sizeof(tunnel_t));
|
||||
*data0 = (tunnel_t)
|
||||
{
|
||||
.connection = connection1,
|
||||
.request_number = request_number1,
|
||||
};
|
||||
tunnel_t* data1 = tf_malloc(sizeof(tunnel_t));
|
||||
*data1 = (tunnel_t)
|
||||
{
|
||||
.connection = connection0,
|
||||
.request_number = request_number0,
|
||||
};
|
||||
|
||||
printf("ADD REQUEST %p %d\n", connection0, request_number0);
|
||||
printf("ADD REQUEST %p %d\n", connection1, request_number1);
|
||||
tf_ssb_connection_add_request(connection0, request_number0, _tf_ssb_tunnel_rpc_callback, _tf_ssb_tunnel_cleanup, data0);
|
||||
tf_ssb_connection_add_request(connection1, request_number1, _tf_ssb_tunnel_rpc_callback, _tf_ssb_tunnel_cleanup, data1);
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
||||
{
|
||||
JS_NewClassID(&_tf_ssb_classId);
|
||||
@ -919,10 +1024,13 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
||||
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 2));
|
||||
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
||||
JS_SetPropertyStr(context, object, "connections", JS_NewCFunction(context, _tf_ssb_connections, "connections", 0));
|
||||
JS_SetPropertyStr(context, object, "getConnection", JS_NewCFunction(context, _tf_ssb_getConnection, "getConnection", 1));
|
||||
JS_SetPropertyStr(context, object, "sqlStream", JS_NewCFunction(context, _tf_ssb_sqlStream, "sqlStream", 3));
|
||||
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
|
||||
JS_SetPropertyStr(context, object, "getBroadcasts", JS_NewCFunction(context, _tf_ssb_getBroadcasts, "getBroadcasts", 0));
|
||||
JS_SetPropertyStr(context, object, "connect", JS_NewCFunction(context, _tf_ssb_connect, "connect", 1));
|
||||
JS_SetPropertyStr(context, object, "createTunnel", JS_NewCFunction(context, _tf_ssb_createTunnel, "createTunnel", 3));
|
||||
JS_SetPropertyStr(context, object, "tunnel", JS_NewCFunction(context, _tf_ssb_tunnel, "tunnel", 4));
|
||||
|
||||
/* Should be trusted only. */
|
||||
JS_SetPropertyStr(context, object, "addRpc", JS_NewCFunction(context, _tf_ssb_add_rpc, "addRpc", 2));
|
||||
|
Reference in New Issue
Block a user