Skip to content

Commit

Permalink
Attempt to handle callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
mgdm committed Sep 16, 2013
1 parent 8edb95c commit 8e3e1b1
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
104 changes: 102 additions & 2 deletions mosquitto.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

#include "php.h"
#include "php_ini.h"
#include "zend_variables.h"
#include "zend_exceptions.h"
#include "zend_API.h"
#include "ext/standard/info.h"
#include "php_mosquitto.h"

Expand Down Expand Up @@ -36,6 +38,8 @@ PHP_METHOD(Mosquitto_Client, __construct)
strerror_r(errno, buf, 0x100);
zend_throw_exception(mosquitto_ce_exception, buf, 1 TSRMLS_CC);
}

mosquitto_connect_callback_set(object->client, php_mosquitto_connect_callback);
}
/* }}} */

Expand All @@ -47,23 +51,88 @@ PHP_METHOD(Mosquitto_Client, connect)
int host_len, interface_len, retval;
long port = 1883;
long keepalive = 0;
zend_fcall_info *connect_callback;
zend_fcall_info_cache *connect_callback_cache;

PHP_MOSQUITTO_ERROR_HANDLING();
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lls!",
&host, &host_len, &port, &keepalive, &interface, &interface_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lls!f!",
&host, &host_len, &port, &keepalive, &interface, &interface_len, &connect_callback, &connect_callback_cache) == FAILURE) {
PHP_MOSQUITTO_RESTORE_ERRORS();
return;
}
PHP_MOSQUITTO_RESTORE_ERRORS();

object = (mosquitto_client_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
object->connect_callback = connect_callback;
object->connect_callback_cache = connect_callback_cache;
retval = mosquitto_connect(object->client, host, port, keepalive);

if (retval == MOSQ_ERR_INVAL) {
zend_throw_exception(mosquitto_ce_exception, "Invalid parameters", 0 TSRMLS_CC);
} else if (retval == MOSQ_ERR_ERRNO) {
char buf[0x100];
strerror_r(errno, buf, 0x100);
zend_throw_exception(mosquitto_ce_exception, buf, 1 TSRMLS_CC);
}
}
/* }}} */

/* {{{ */
PHP_METHOD(Mosquitto_Client, publish)
{
mosquitto_client_object *object;
int mid, topic_len, payload_len, retval;
long qos;
zend_bool retain;
char *topic, *payload;

PHP_MOSQUITTO_ERROR_HANDLING();
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sslb",
&topic, &topic_len, &payload, &payload_len, &qos, &retain) == FAILURE) {
PHP_MOSQUITTO_RESTORE_ERRORS();
return;
}
PHP_MOSQUITTO_RESTORE_ERRORS();

object = (mosquitto_client_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
retval = mosquitto_publish(object->client, &mid, topic, payload_len, (void *) payload, qos, retain);

if (retval != MOSQ_ERR_SUCCESS) {
char buf[0x100];
strerror_r(errno, buf, 0x100);
zend_throw_exception(mosquitto_ce_exception, buf, 1 TSRMLS_CC);
}

char *message = NULL;
switch (retval) {
case MOSQ_ERR_SUCCESS:
default:
RETURN_LONG(mid);
break;

case MOSQ_ERR_INVAL:
message = estrdup("Invalid input parameter");
break;

case MOSQ_ERR_NOMEM:
message = estrdup("Insufficient memory");
break;

case MOSQ_ERR_NO_CONN:
message = estrdup("The client is not connected to a broker");
break;

case MOSQ_ERR_PROTOCOL:
message = estrdup("There was a protocol error communicating with the broker.");
break;

case MOSQ_ERR_PAYLOAD_SIZE:
message = estrdup("Payload is too large");
break;

}
zend_throw_exception(mosquitto_ce_exception, message, 0 TSRMLS_CC);
efree(message);
}
/* }}} */

Expand Down Expand Up @@ -99,10 +168,41 @@ static zend_object_value mosquitto_client_object_new() {
return retval;
}

PHP_MOSQUITTO_API void php_mosquitto_connect_callback(struct mosquitto *mosq, void *obj, int rc)
{
mosquitto_client_object *object = (mosquitto_client_object *) obj;
zval *params[1], *retval_ptr = NULL;

if (object->connect_callback == NULL) {
return;
}

ALLOC_INIT_ZVAL(params[0]);
ZVAL_LONG(params[0], rc);

object->connect_callback->params = params;
object->connect_callback->param_count = 1;
object->connect_callback->retval_ptr_ptr = &retval_ptr;
object->connect_callback->no_separation = 1;

if (zend_call_function(object->connect_callback, object->connect_callback_cache TSRMLS_CC) == FAILURE) {
if (!EG(exception)) {
zend_throw_exception_ex(mosquitto_ce_exception, 0 TSRMLS_CC, "Failed to invoke connect callback %s()", Z_STRVAL_P(object->connect_callback->function_name));
}
}

zval_ptr_dtor(params);

if (retval_ptr != NULL) {
zval_ptr_dtor(&retval_ptr);
}
}

/* {{{ mosquitto_client_methods */
const zend_function_entry mosquitto_client_methods[] = {
PHP_ME(Mosquitto_Client, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(Mosquitto_Client, connect, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Mosquitto_Client, publish, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* }}} */
Expand Down
4 changes: 4 additions & 0 deletions php_mosquitto.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ extern zend_module_entry mosquitto_module_entry;
typedef struct _mosquitto_client_object {
zend_object std;
struct mosquitto *client;
zend_fcall_info *connect_callback;
zend_fcall_info_cache *connect_callback_cache;
} mosquitto_client_object;

PHP_MOSQUITTO_API void php_mosquitto_connect_callback(struct mosquitto *mosq, void *obj, int rc);

PHP_MINIT_FUNCTION(mosquitto);
PHP_MSHUTDOWN_FUNCTION(mosquitto);
PHP_MINFO_FUNCTION(mosquitto);
Expand Down

0 comments on commit 8e3e1b1

Please sign in to comment.