lm_connection.c
changeset 0 84fdfb0344c9
child 1 64a857d6b81b
equal deleted inserted replaced
-1:000000000000 0:84fdfb0344c9
       
     1 
       
     2 #include <lua.h>
       
     3 #include <lauxlib.h>
       
     4 #include <glib.h>			// GDestroyNotify, GMainContext
       
     5 #include <loudmouth/loudmouth.h>
       
     6 
       
     7 #include "util.h"
       
     8 #include "lm_types.h"
       
     9 #include "lm_message.h"
       
    10 #include "lm_message_handler.h"
       
    11 
       
    12 /// lm.connection
       
    13 /// Central module, representing connection to the server.
       
    14 /// You should create a new connection object, then open it (establish
       
    15 /// connection), then authenticate to the server.
       
    16 
       
    17 /// connection state
       
    18 /// Stirng, representing current connection state.
       
    19 /// V: closed, opening, open, authenticating, authenticated
       
    20 const string2enum_t llm_connection_state[] = {
       
    21 	{ "closed",         LM_CONNECTION_STATE_CLOSED         },
       
    22 	{ "opening",        LM_CONNECTION_STATE_OPENING        },
       
    23 	{ "open",           LM_CONNECTION_STATE_OPEN           },
       
    24 	{ "authenticating", LM_CONNECTION_STATE_AUTHENTICATING },
       
    25 	{ "authenticated",  LM_CONNECTION_STATE_AUTHENTICATED  },
       
    26 	{ NULL,             0                                  }, // XXX
       
    27 };
       
    28 
       
    29 /// handler priority
       
    30 /// String, according to which handler will be placed into one
       
    31 /// of three handler groups.
       
    32 /// V: last, normal, first
       
    33 const string2enum_t llm_handler_priority[] = {
       
    34 	{ "last",   LM_HANDLER_PRIORITY_LAST   },
       
    35 	{ "normal", LM_HANDLER_PRIORITY_NORMAL },
       
    36 	{ "first",  LM_HANDLER_PRIORITY_FIRST  },
       
    37 	{ NULL,     0                          }, // XXX
       
    38 };
       
    39 
       
    40 /// disconnect reason
       
    41 /// String, indicating the reason of disconnection occured.
       
    42 /// V: ok, ping time out, hup, error, resource conflict, invalid xml, unknown, ping_time_out, resource_conflict, invalid_xml
       
    43 const string2enum_t llm_disconnect_reason[] = {
       
    44 	{ "ok",                LM_DISCONNECT_REASON_OK                },
       
    45 	{ "ping time out",     LM_DISCONNECT_REASON_PING_TIME_OUT     },
       
    46 	{ "hup",               LM_DISCONNECT_REASON_HUP               },
       
    47 	{ "error",             LM_DISCONNECT_REASON_ERROR             },
       
    48 	{ "resource conflict", LM_DISCONNECT_REASON_RESOURCE_CONFLICT },
       
    49 	{ "invalid xml",       LM_DISCONNECT_REASON_INVALID_XML       },
       
    50 	{ "unknown",           LM_DISCONNECT_REASON_UNKNOWN           },
       
    51 	{ "ping_time_out",     LM_DISCONNECT_REASON_PING_TIME_OUT     },
       
    52 	{ "resource_conflict", LM_DISCONNECT_REASON_RESOURCE_CONFLICT },
       
    53 	{ "invalid_xml",       LM_DISCONNECT_REASON_INVALID_XML       },
       
    54 	{ NULL,                0                                      }, // XXX
       
    55 };
       
    56 
       
    57 /// lm.connection.new
       
    58 /// Creates a new connection (closed).
       
    59 /// A: string (server name), lightuserdata (C glib main context object, optional)
       
    60 /// R: lm connection object
       
    61 static int llm_connection_new (lua_State *L)
       
    62 {
       
    63 	const char *server = luaL_checkstring (L, 1);
       
    64 	LmConnection *connection;
       
    65 	if (lua_gettop (L) < 2) {
       
    66 		connection = lm_connection_new (server);
       
    67 		lua_pop (L, 1);
       
    68 	} else {
       
    69 		luaL_argcheck (L, lua_islightuserdata (L, 2), 2, "glib main context lightuserdata expected");
       
    70 		connection = lm_connection_new_with_context (server, (GMainContext *) lua_touserdata (L, 2));
       
    71 		lua_pop (L, 2);
       
    72 	}
       
    73 	llm_connection_bless (L, connection);
       
    74 	lm_connection_unref (connection);
       
    75 	return 1;
       
    76 }
       
    77 
       
    78 /// lm.connection.bless
       
    79 /// Blesses given pointer to lm connection object.
       
    80 /// Note: it adds a reference to connection.
       
    81 /// A: lightuserdata (C lm connection object)
       
    82 /// R: lm connection object
       
    83 static int llm_connection_bless_lua (lua_State *L)
       
    84 {
       
    85 	luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth connection lightuserdata expected");
       
    86 	llm_connection_bless (L, (LmConnection *) lua_touserdata (L, 1));
       
    87 	lua_remove (L, -2);
       
    88 	return 1;
       
    89 }
       
    90 
       
    91 /// connection callback function
       
    92 /// User function, that will be called on connection establishment operation end,
       
    93 /// eg. successful/unsuccessful opening or authentication.
       
    94 /// A: lm connection object, boolean (success)
       
    95 static void llm_connection_callback (LmConnection *connection, int success, llm_callback_t *cb)
       
    96 {
       
    97 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
       
    98 	llm_connection_bless (cb->L, connection);
       
    99 	// XXX lm_connection_unref (connection);
       
   100 	lua_pushboolean (cb->L, success);
       
   101 	if (lua_pcall (cb->L, 2, 0, 0)) {
       
   102 		// XXX lua_error (cb->L);
       
   103 		lua_pop (cb->L, 1);
       
   104 		return;
       
   105 	}
       
   106 }
       
   107 
       
   108 /// connection:open
       
   109 /// Opens connection to the server and then calls callback function.
       
   110 /// A: connection callback function
       
   111 /// R: boolean (success)
       
   112 static int llm_connection_open (lua_State *L)
       
   113 {
       
   114 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   115 	llm_callback_t *cb;
       
   116 	luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
       
   117 	
       
   118 	cb = luaL_malloc (L, sizeof (llm_callback_t));
       
   119 	cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
       
   120 	cb->L         = L;
       
   121 
       
   122 	lua_pushboolean (L, lm_connection_open (object->connection,
       
   123 						(LmResultFunction)llm_connection_callback, cb,
       
   124 						(GDestroyNotify)llm_callback_destroy, NULL));
       
   125 	lua_remove (L, -2);
       
   126 	return 1;
       
   127 }
       
   128 
       
   129 /// connection:authenticate
       
   130 /// Tries to authenticate against opened connection, then calls callback function.
       
   131 /// A: string (username), string (password), string (resource), connection callback function
       
   132 /// R: boolean (success)
       
   133 static int llm_connection_authenticate (lua_State *L)
       
   134 {
       
   135 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   136 	const char *username = luaL_checkstring (L, 2);
       
   137 	const char *password = luaL_checkstring (L, 3);
       
   138 	const char *resource = luaL_checkstring (L, 4);
       
   139 	llm_callback_t *cb;
       
   140 	int status;
       
   141 	luaL_argcheck (L, lua_isfunction (L, 5), 5, "function expected");
       
   142 
       
   143 	cb = luaL_malloc (L, sizeof (llm_callback_t));
       
   144 	cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
       
   145 	cb->L         = L;
       
   146 
       
   147 	status = lm_connection_authenticate (object->connection, username, password, resource,
       
   148 						(LmResultFunction)llm_connection_callback, cb,
       
   149 						(GDestroyNotify)llm_callback_destroy, NULL);
       
   150 	lua_pop (L, 4);
       
   151 	lua_pushboolean (L, status);
       
   152 	return 1;
       
   153 }
       
   154 
       
   155 /// connection:port
       
   156 /// Gets or sets server port to connect.
       
   157 /// A: integer (optional)
       
   158 /// R: integer (when called with no args)
       
   159 static int llm_connection_port (lua_State *L)
       
   160 {
       
   161 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   162 	if (lua_gettop (L) > 1) { // Set
       
   163 		lm_connection_set_port (object->connection, luaL_checkint (L, 2));
       
   164 		lua_pop (L, 2);
       
   165 		return 0;
       
   166 	} else { // Get
       
   167 		lua_pushnumber (L, lm_connection_get_port (object->connection));
       
   168 		lua_remove (L, -2);
       
   169 		return 1;
       
   170 	}
       
   171 }
       
   172 
       
   173 /// connection:server
       
   174 /// Gets or sets server to connect to.
       
   175 /// A: string (optional, server name)
       
   176 /// R: string (when called with no args)
       
   177 static int llm_connection_server (lua_State *L)
       
   178 {
       
   179 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   180 	if (lua_gettop (L) > 1) { // Set
       
   181 		lm_connection_set_server (object->connection, luaL_checkstring (L, 2));
       
   182 		lua_pop (L, 2);
       
   183 		return 0;
       
   184 	} else { // Get
       
   185 		lua_pushstring (L, lm_connection_get_server (object->connection));
       
   186 		lua_remove (L, -2);
       
   187 		return 1;
       
   188 	}
       
   189 }
       
   190 
       
   191 /// connection:jid
       
   192 /// Gets or sets jid for connection.
       
   193 /// A: string (optional)
       
   194 /// R: string (when called with no args)
       
   195 static int llm_connection_jid (lua_State *L)
       
   196 {
       
   197 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   198 	if (lua_gettop (L) > 1) { // Set
       
   199 		lm_connection_set_jid (object->connection, luaL_checkstring (L, 2));
       
   200 		lua_pop (L, 2);
       
   201 		return 0;
       
   202 	} else { // Get
       
   203 		lua_pushstring (L, lm_connection_get_jid (object->connection));
       
   204 		lua_remove (L, -2);
       
   205 		return 1;
       
   206 	}
       
   207 }
       
   208 
       
   209 /// connection:keep_alive_rate
       
   210 /// Gets or sets keep alive packets rate for connection.
       
   211 /// Note, that on some platforms there is no get function even in
       
   212 /// loudmouth versions, that should have it according to documentation.
       
   213 /// integer (optional, seconds)
       
   214 /// integer (when called with no args)
       
   215 static int llm_connection_keep_alive_rate (lua_State *L)
       
   216 {
       
   217 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   218 	if (lua_gettop (L) > 1) { // Set
       
   219 		lm_connection_set_keep_alive_rate (object->connection, luaL_checkint (L, 2));
       
   220 		lua_pop (L, 2);
       
   221 		return 0;
       
   222 	} else { // Get
       
   223 #ifdef HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE
       
   224 		lua_pushnumber (L, lm_connection_get_keep_alive_rate (object->connection));
       
   225 		lua_remove (L, -2);
       
   226 #else
       
   227 		lua_pop (L, 1);
       
   228 		lua_pushstring (L, "Sorry, your loudmouth have no get_keep_alive_rate");
       
   229 		lua_error (L);
       
   230 #endif
       
   231 		return 1;
       
   232 	}
       
   233 }
       
   234 
       
   235 /// connection:proxy
       
   236 /// Gets or sets proxy server for connection.
       
   237 /// A: lm proxy object (optional)
       
   238 /// R: lm proxy object or nil (when called with no args)
       
   239 static int llm_connection_proxy (lua_State *L)
       
   240 {
       
   241 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   242 	if (lua_gettop (L) > 1) { // Set
       
   243 		llm_proxy_t *proxy = luaL_checklm_proxy (L, 2);
       
   244 		lm_connection_set_proxy (object->connection, proxy->proxy);
       
   245 		lua_pop (L, 2);
       
   246 		return 0;
       
   247 	} else { // Get
       
   248 		LmProxy *proxy = lm_connection_get_proxy (object->connection);
       
   249 		lua_pop (L, 1);
       
   250 		if (proxy) {
       
   251 			llm_proxy_bless (L, proxy);
       
   252 			// XXX lm_proxy_unref (proxy);
       
   253 		} else
       
   254 			lua_pushnil (L);
       
   255 		return 1;
       
   256 	}
       
   257 }
       
   258 
       
   259 /// connection:ssl
       
   260 /// Gets or sets ssl object for connection.
       
   261 /// A: lm ssl object (optional)
       
   262 /// R: lm ssl object or nil (when called with no args)
       
   263 static int llm_connection_ssl (lua_State *L)
       
   264 {
       
   265 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   266 	if (lua_gettop (L) > 1) { // Set
       
   267 		llm_ssl_t *ssl = luaL_checklm_ssl (L, 2);
       
   268 		lm_connection_set_ssl (object->connection, ssl->ssl);
       
   269 		lua_pop (L, 2);
       
   270 		return 0;
       
   271 	} else { // Get
       
   272 		LmSSL *ssl = lm_connection_get_ssl (object->connection);
       
   273 		lua_pop (L, 1);
       
   274 		if (ssl) {
       
   275 			llm_ssl_bless (L, ssl);
       
   276 			// XXX lm_ssl_unref (ssl);
       
   277 		} else
       
   278 			lua_pushnil (L);
       
   279 		return 1;
       
   280 	}
       
   281 }
       
   282 
       
   283 /// connection:close
       
   284 /// Close connection.
       
   285 /// R: boolean (success)
       
   286 static int llm_connection_close (lua_State *L)
       
   287 {
       
   288 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   289 	lua_pushboolean (L, lm_connection_close (object->connection, NULL));
       
   290 	lua_remove (L, -2);
       
   291 	return 1;
       
   292 }
       
   293 
       
   294 /// connection:status
       
   295 /// Returns string, describing connection state.
       
   296 /// R: connection state
       
   297 static int llm_connection_status (lua_State *L)
       
   298 {
       
   299 	llm_connection_t *connection = luaL_checklm_connection (L, 1);
       
   300 	luaL_pushenum (L, lm_connection_get_state (connection->connection), llm_connection_state)
       
   301 	lua_remove (L, -2);
       
   302 	return 1;
       
   303 }
       
   304 
       
   305 /// connection:send
       
   306 /// Sends message (object). If specified, handler function will be called upon
       
   307 /// receiving of response to that message.
       
   308 /// Handler function can be either message handler object or just a function.
       
   309 /// A: lm message object, message handler callback function or lm message handler object (optional)
       
   310 /// R: boolean (success)
       
   311 static int llm_connection_send (lua_State *L)
       
   312 {
       
   313 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   314 	llm_message_t *message = luaL_checklm_message (L, 2);
       
   315 	int status;
       
   316 	if (lua_gettop (L) < 3) // Send
       
   317 		status = lm_connection_send (object->connection, message->message, NULL);
       
   318 	else if (lua_isfunction (L, 3)) { // Send w/reply, func
       
   319 		llm_callback_t *cb = luaL_malloc (L, sizeof (llm_callback_t));
       
   320 		LmMessageHandler *handler;
       
   321 
       
   322 		cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
       
   323 		cb->L = L;
       
   324 		handler = lm_message_handler_new (
       
   325 					(LmHandleMessageFunction)llm_message_handler_callback,
       
   326 					cb, (GDestroyNotify)llm_callback_destroy);
       
   327 		status = lm_connection_send_with_reply (object->connection,
       
   328 							message->message, handler, NULL);
       
   329 		lm_message_handler_unref (handler);
       
   330 	} else { // Send w/reply, handler
       
   331 		llm_message_handler_t *handler = luaL_checklm_message_handler (L, 3);
       
   332 		status = lm_connection_send_with_reply (object->connection, message->message,
       
   333 							handler->message_handler, NULL);
       
   334 		lua_pop (L, 1);
       
   335 	};
       
   336 	lua_pop (L, 2);
       
   337 	lua_pushboolean (L, status);
       
   338 	return 1;
       
   339 }
       
   340 
       
   341 /// connection:send_raw
       
   342 /// Sends arbitrary string to opened connection.
       
   343 /// A: string
       
   344 /// R: boolean (status)
       
   345 static int llm_connection_send_raw (lua_State *L)
       
   346 {
       
   347 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   348 	const char *string = luaL_checkstring (L, 2);
       
   349 	int status = lm_connection_send_raw (object->connection, string, NULL);
       
   350 	lua_pop (L, 2);
       
   351 	lua_pushboolean (L, status);
       
   352 	return 1;
       
   353 }
       
   354 
       
   355 /// connection:handler
       
   356 /// Registers or unregisters handler function for a given type of messages.
       
   357 /// To unregister handler, omit the priority argument.
       
   358 /// Handler function can be specified as plain function or message handler object.
       
   359 /// Though, you can unregister only a message handler object.
       
   360 /// A: message handler callback function or lm message handler object, message type, handler priority (optional)
       
   361 static int llm_connection_handler (lua_State *L)
       
   362 {
       
   363 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   364 	int type = luaL_checkenum (L, 3, llm_message_type);
       
   365 
       
   366 	if (lua_gettop (L) > 3) { // Register
       
   367 		int priority = luaL_checkenum (L, 4, llm_handler_priority);
       
   368 
       
   369 		if (lua_isfunction (L, 2)) { // Function
       
   370 			LmMessageHandler *handler;
       
   371 			llm_callback_t *cb = luaL_malloc (L, sizeof (llm_callback_t));
       
   372 			lua_pushvalue (L, 2);
       
   373 			cb->reference = luaL_ref (L, LUA_REGISTRYINDEX);
       
   374 			cb->L         = L;
       
   375 
       
   376 			handler = lm_message_handler_new (
       
   377 					(LmHandleMessageFunction)llm_message_handler_callback,
       
   378 					cb, (GDestroyNotify)llm_callback_destroy);
       
   379 			lm_connection_register_message_handler (object->connection,
       
   380 								handler, type, priority);
       
   381 			lm_message_handler_unref (handler);
       
   382 		} else { // Object
       
   383 			llm_message_handler_t *handler = luaL_checklm_message_handler (L, 2);
       
   384 			lm_connection_register_message_handler (object->connection,
       
   385 								handler->message_handler,
       
   386 								type, priority);
       
   387 		}
       
   388 		lua_pop (L, 1);
       
   389 	} else { // Unregister
       
   390 		llm_message_handler_t *handler = luaL_checklm_message_handler (L, 2);
       
   391 		lm_connection_unregister_message_handler (object->connection,
       
   392 							  handler->message_handler,
       
   393 							  type);
       
   394 	}
       
   395 	lua_pop (L, 2);
       
   396 	return 0;
       
   397 }
       
   398 
       
   399 /// disconnect callback function
       
   400 /// Function, that will be called when disconnection occurs.
       
   401 /// A: lm connection object, disconnect reason
       
   402 void llm_disconnect_callback (LmConnection *connection, LmDisconnectReason reason, llm_callback_t *cb)
       
   403 {
       
   404 	lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference);
       
   405 	llm_connection_bless (cb->L, connection);
       
   406 	// XXX lm_connection_unref (connection);
       
   407 	luaL_pushenum (cb->L, reason, llm_disconnect_reason);
       
   408 	if (lua_pcall (cb->L, 2, 0, 0)) {
       
   409 		// XXX lua_error (cb->L);
       
   410 		lua_pop (cb->L, 1);
       
   411 		return;
       
   412 	}
       
   413 }
       
   414 
       
   415 /// connection:ondisconnect
       
   416 /// Sets callback, that will be called on connection disconnect.
       
   417 /// A: disconnect callback function
       
   418 static int llm_connection_ondisconnect (lua_State *L)
       
   419 {
       
   420 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   421 	llm_callback_t *cb;
       
   422 	luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected");
       
   423 
       
   424 	cb = luaL_malloc (L, sizeof (llm_callback_t));
       
   425 	cb->reference  = luaL_ref (L, LUA_REGISTRYINDEX);
       
   426 	cb->L          = L;
       
   427 
       
   428 	lm_connection_set_disconnect_function (object->connection,
       
   429 					       (LmDisconnectFunction)llm_disconnect_callback,
       
   430 					       cb, (GDestroyNotify)llm_callback_destroy);
       
   431 	lua_pop (L, 1);
       
   432 	return 0;
       
   433 }
       
   434 
       
   435 /// connection:open_wait
       
   436 /// Synchronous open call, that will block until connection will be opened.
       
   437 /// R: boolean (success)
       
   438 static int llm_connection_open_wait (lua_State *L)
       
   439 {
       
   440 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   441 	lua_pushboolean (L, lm_connection_open_and_block (object->connection, NULL));
       
   442 	lua_remove (L, -2);
       
   443 	return 1;
       
   444 }
       
   445 
       
   446 /// connection:authenticate_wait
       
   447 /// Synchronous authentication call, that will wait until the end of authentication.
       
   448 /// A: string (username), string (password), string (resource)
       
   449 /// R: boolean (success)
       
   450 static int llm_connection_authenticate_wait (lua_State *L)
       
   451 {
       
   452 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   453 	const char *username = luaL_checkstring (L, 2);
       
   454 	const char *password = luaL_checkstring (L, 3);
       
   455 	const char *resource = luaL_checkstring (L, 4);
       
   456 	int status = lm_connection_authenticate_and_block (object->connection, username,
       
   457 								password, resource, NULL);
       
   458 	lua_pop (L, 4);
       
   459 	lua_pushboolean (L, status);
       
   460 	return 1;
       
   461 }
       
   462 
       
   463 /// connection:send_wait
       
   464 /// Synchronous call, that will send message and wait for reply to it.
       
   465 /// A: lm message object
       
   466 /// R: lm message object or nil
       
   467 static int llm_connection_send_wait (lua_State *L)
       
   468 {
       
   469 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   470 	llm_message_t *message = luaL_checklm_message (L, 2);
       
   471 	LmMessage *new = lm_connection_send_with_reply_and_block (object->connection,
       
   472 									message->message, NULL);
       
   473 	lua_pop (L, 2);
       
   474 	if (!new)
       
   475 		lua_pushnil (L);
       
   476 	else {
       
   477 		llm_message_bless (L, new);
       
   478 		lm_message_unref (new); // XXX
       
   479 	}
       
   480 	return 1;
       
   481 }
       
   482 
       
   483 /// connection:pointer
       
   484 /// Returns pointer to underlying C loudmouth structure.
       
   485 /// R: lightuserdata
       
   486 static int llm_connection_pointer (lua_State *L)
       
   487 {
       
   488 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   489 	lua_pushlightuserdata (L, object->connection);
       
   490 	lua_remove (L, -2);
       
   491 	return 1;
       
   492 }
       
   493 
       
   494 static int llm_connection_gc (lua_State *L)
       
   495 {
       
   496 	llm_connection_t *object = luaL_checklm_connection (L, 1);
       
   497 	lm_connection_unref (object->connection);
       
   498 	lua_pop (L, 1);
       
   499 	return 0;
       
   500 }
       
   501 
       
   502 static const luaL_Reg llm_connection_reg_f[] = {
       
   503 	{ "new",   llm_connection_new       },
       
   504 	{ "bless", llm_connection_bless_lua },
       
   505 	{ NULL,    NULL                     },
       
   506 };
       
   507 
       
   508 static const luaL_Reg llm_connection_reg_m[] = {
       
   509 	{ "open",                llm_connection_open                },
       
   510 	{ "close",               llm_connection_close               },
       
   511 	{ "authenticate",        llm_connection_authenticate        },
       
   512 	{ "port",                llm_connection_port                },
       
   513 	{ "server",              llm_connection_server              },
       
   514 	{ "jid",                 llm_connection_jid                 },
       
   515 	{ "keep_alive_rate",     llm_connection_keep_alive_rate     },
       
   516 	{ "state",               llm_connection_status              },
       
   517 	{ "proxy",               llm_connection_proxy               },
       
   518 	{ "ssl",                 llm_connection_ssl                 },
       
   519 	{ "send",                llm_connection_send                },
       
   520 	{ "send_raw",            llm_connection_send_raw            },
       
   521 	{ "handler",             llm_connection_handler             },
       
   522 	{ "ondisconnect",        llm_connection_ondisconnect        },
       
   523 	{ "open_wait",           llm_connection_open_wait           },
       
   524 	{ "authenticate_wait",   llm_connection_authenticate_wait   },
       
   525 	{ "send_wait",           llm_connection_send_wait           },
       
   526 	{ "pointer",             llm_connection_pointer             },
       
   527 	{ "__gc",                llm_connection_gc                  },
       
   528 	{ NULL,                  NULL                               },
       
   529 };
       
   530 
       
   531 int luaopen_lm_connection (lua_State *L)
       
   532 {
       
   533 	luaL_newmetatable (L, "loudmouth.connection");
       
   534 	lua_pushstring (L, "__index");
       
   535 	lua_pushvalue (L, -2);
       
   536 	lua_settable (L, -3);
       
   537 	luaL_register (L, NULL, llm_connection_reg_m);
       
   538 	lua_pop (L, 1);
       
   539 	luaL_register (L, "lm.connection", llm_connection_reg_f);
       
   540 	return 1;
       
   541 }
       
   542