Commit 2708378d2177da44a4571168cb0f3e9783d9cb96
1 parent
294187800e
Exists in
master
start
Signed-off-by: Tom Huang <tom_huang@sanlien.com.tw>
Showing
4 changed files
with
1092 additions
and
0 deletions
Show diff stats
README.md
| File was created | 1 | # Mosquitto-PHP | |
| 2 | |||
| 3 | This is an extension to allow using the [Mosquitto MQTT library](http://mosquitto.org) with PHP. See the examples/ directory for usage. | ||
| 4 | |||
| 5 | [](https://travis-ci.org/mgdm/Mosquitto-PHP) | ||
| 6 | |||
| 7 | ## Requirements | ||
| 8 | |||
| 9 | * PHP 5.3+ | ||
| 10 | * libmosquitto 1.2.x | ||
| 11 | * Linux or Mac OS X. I do not have a Windows machine handy, though patches or | ||
| 12 | pull requests are of course very welcome! | ||
| 13 | |||
| 14 | ## Installation | ||
| 15 | |||
| 16 | You may obtain this package using [PECL](http://pecl.php.net): | ||
| 17 | |||
| 18 | ```` | ||
| 19 | pecl install Mosquitto-alpha | ||
| 20 | ```` | ||
| 21 | |||
| 22 | Alternatively, you can use the normal extension build process: | ||
| 23 | |||
| 24 | ```` | ||
| 25 | phpize | ||
| 26 | ./configure --with-mosquitto=/path/to/libmosquitto | ||
| 27 | make | ||
| 28 | make install | ||
| 29 | ```` | ||
| 30 | |||
| 31 | Then add `extension=mosquitto.so` to your `php.ini`. | ||
| 32 | |||
| 33 | The `--with-mosquitto` argument is optional, and only required if your | ||
| 34 | libmosquitto install cannot be found. | ||
| 35 | |||
| 36 | ## Documentation | ||
| 37 | |||
| 38 | The classes in this extension are namespaced. | ||
| 39 | |||
| 40 | ### Class Mosquitto\Client | ||
| 41 | |||
| 42 | This is the actual Mosquitto client. | ||
| 43 | |||
| 44 | 1. [__construct](#__construct) - create a new client | ||
| 45 | 1. [setCredentials](#setcredentials) - set the credentials to use on connection | ||
| 46 | 1. [setTlsCertificates](#settlscertificates) - set the TLS certificate sources | ||
| 47 | 1. [setTlsInsecure](#settlsinsecure) - Set verification of the server hostname | ||
| 48 | in TLS certificates | ||
| 49 | 1. [setTlsOptions](#settlsoptions) - Set advanced TLS options | ||
| 50 | 1. [setTlsPSK](#settlspsk) - Configure the client for pre-shared-key based TLS | ||
| 51 | support. | ||
| 52 | 1. [setWill](#setwill) - set the client will, to be delivered if disconnected | ||
| 53 | uncleanly | ||
| 54 | 1. [clearWill](#clearwill) - clear a previously-set will | ||
| 55 | 1. [setReconnectDelay](#setreconnectdelay) - set the behaviour if disconnected | ||
| 56 | uncleanly | ||
| 57 | 1. [connect](#connect) - connect to an MQTT broker | ||
| 58 | 1. [disconnect](#disconnect) - disconnect from an MQTT broker | ||
| 59 | 1. [onConnect](#onconnect) - set the connect callback | ||
| 60 | 1. [onDisconnect](#ondisconnect) - set the disconnect callback | ||
| 61 | 1. [onLog](#onlog) - set the logging callback | ||
| 62 | 1. [onSubscribe](#onsubscribe) - set the subscribe callback | ||
| 63 | 1. [onMessage](#onmessage) - set the callback fired when a message is received | ||
| 64 | 1. [setMaxInFlightMessages](#setmaxinflightmessages) - set the number of QoS | ||
| 65 | 1 and 2 messages that can be "in flight" at once | ||
| 66 | 1. [setMessageRetry](#setmessageretry) - set the number of seconds to wait | ||
| 67 | before retrying messages | ||
| 68 | 1. [publish](#publish) - publish a message to a broker | ||
| 69 | 1. [subscribe](#subscribe) - subscribe to a topic | ||
| 70 | 1. [unsubscribe](#unsubscribe) - unsubscribe from a topic | ||
| 71 | 1. [loop](#loop) - The main network loop | ||
| 72 | 1. [loopForever](#loopforever) - run loop() in an infinite blocking loop | ||
| 73 | |||
| 74 | #### __construct | ||
| 75 | |||
| 76 | Creates a new Client instance. | ||
| 77 | |||
| 78 | | Parameter | Type | Description | | ||
| 79 | | --- | --- | ---- | | ||
| 80 | | id | string | Client ID. Optional. If not supplied or NULL, one will be generated at random. | | ||
| 81 | | clean_session | boolean | Set to true to instruct the broker to clean all messages and subscriptions on disconnect. | | ||
| 82 | |||
| 83 | #### setCredentials | ||
| 84 | |||
| 85 | Set the username and password to use on connecting to the broker. Must be | ||
| 86 | called before connect(). | ||
| 87 | |||
| 88 | | Parameter | Type | Description | | ||
| 89 | | --- | --- | ---- | | ||
| 90 | | Username | string | Username to supply to the broker | | ||
| 91 | | Password | string | Password to supply to the broker | | ||
| 92 | |||
| 93 | #### setTlsCertificates | ||
| 94 | |||
| 95 | Configure the client for certificate based SSL/TLS support. Must be called | ||
| 96 | before connect(). Cannot be used in conjunction with setTlsPSK(). | ||
| 97 | |||
| 98 | Define the Certificate Authority certificates to be trusted (ie. the server | ||
| 99 | certificate must be signed with one of these certificates) using cafile. | ||
| 100 | If the server you are connecting to requires clients to provide a certificate, | ||
| 101 | define certfile and keyfile with your client certificate and private key. If | ||
| 102 | your private key is encrypted, provide the password as the fourth parameter, or | ||
| 103 | you will have to enter the password at the command line. | ||
| 104 | |||
| 105 | | Parameter | Type | Description | | ||
| 106 | | --- | --- | ---- | | ||
| 107 | | capath | string | Path to the PEM encoded trusted CA certificate files, or to a directory containing them | | ||
| 108 | | certfile | string | Path to the PEM encoded certificate file for this client. Optional. | | ||
| 109 | | keyfile | string | Path to a file containing the PEM encoded private key for this client. Required if certfile is set. | | ||
| 110 | | password | string | The password for the keyfile, if it is encrypted. If null, the password will be asked for on the command line. | | ||
| 111 | |||
| 112 | #### setTlsInsecure | ||
| 113 | |||
| 114 | Configure verification of the server hostname in the server certificate. If | ||
| 115 | value is set to true, it is impossible to guarantee that the host you are | ||
| 116 | connecting to is not impersonating your server. Do not use this function in | ||
| 117 | a real system. Must be called before connect(). | ||
| 118 | |||
| 119 | | Parameter | Type | Description | | ||
| 120 | | --- | --- | ---- | | ||
| 121 | | value | boolean | If set to false, the default, certificate hostname checking is performed. If set to true, no hostname checking is performed and the connection is insecure. | | ||
| 122 | |||
| 123 | #### setTlsOptions | ||
| 124 | |||
| 125 | Set advanced SSL/TLS options. Must be called before connect(). | ||
| 126 | |||
| 127 | | Parameter | Type | Description | | ||
| 128 | | --- | --- | ---- | | ||
| 129 | | certReqs | int | Whether or not to verify the server. Can be Mosquitto\Client::SSL_VERIFY_NONE, to disable certificate verification, or Mosquitto\Client::SSL_VERIFY_PEER (the default), to verify the server certificate. | | ||
| 130 | | tlsVersion | string | The TLS version to use. If NULL, a default is used. The default value depends on the version of OpenSSL the library was compiled against. Available options on OpenSSL >= 1.0.1 are 'tlsv1.2', 'tlsv1.1' and 'tlsv1'. | | ||
| 131 | | cipers | string | A string describing the ciphers available for use. See the `openssl ciphers` tool for more information. If NULL, the default set will be used. | | ||
| 132 | |||
| 133 | #### setTlsPSK | ||
| 134 | |||
| 135 | Configure the client for pre-shared-key based TLS support. Must be called before connect(). Cannot be used in conjunction with setTlsCertificates. | ||
| 136 | |||
| 137 | | Parameter | Type | Description | | ||
| 138 | | --- | --- | ---- | | ||
| 139 | | psk | string | The pre-shared key in hex format with no leading "0x". | ||
| 140 | | identity | string | The identity of this client. May be used as the username depending on server settings. | | ||
| 141 | | cipers | string | Optional. A string describing the ciphers available for use. See the `openssl ciphers` tool for more information. If NULL, the default set will be used. | | ||
| 142 | |||
| 143 | #### setWill | ||
| 144 | |||
| 145 | Set the client "last will and testament", which will be sent on an unclean | ||
| 146 | disconnection from the broker. Must be called before connect(). | ||
| 147 | |||
| 148 | | Parameter | Type | Description | | ||
| 149 | | --- | --- | ---- | | ||
| 150 | | topic | string | The topic on which to publish the will. | | ||
| 151 | | payload | string | The data to send. | | ||
| 152 | | qos | int | Optional. Default 0. Integer 0, 1, or 2 indicating the Quality of Service to be used. | | ||
| 153 | | retain | boolean | Optional. Default false. If true, the message will be retained. | | ||
| 154 | |||
| 155 | #### clearWill | ||
| 156 | |||
| 157 | Remove a previously-set will. No parameters. | ||
| 158 | |||
| 159 | #### setReconnectDelay | ||
| 160 | |||
| 161 | Control the behaviour of the client when it has unexpectedly disconnected in | ||
| 162 | loopForever. The default behaviour if this method is not used is to | ||
| 163 | repeatedly attempt to reconnect with a delay of 1 second until the connection | ||
| 164 | succeeds. | ||
| 165 | |||
| 166 | | Parameter | Type | Description | | ||
| 167 | | --- | --- | ---- | | ||
| 168 | | reconnect_delay | int | Set delay between successive reconnection attempts. | | ||
| 169 | | reconnect_delay | int | Set max delay between successive reconnection attempts when exponential backoff is enabled | | ||
| 170 | | exponential_backoff | bool | Enable exponential backoff | | ||
| 171 | |||
| 172 | #### connect | ||
| 173 | |||
| 174 | Connect to an MQTT broker. | ||
| 175 | |||
| 176 | | Parameter | Type | Description | | ||
| 177 | | --- | --- | ---- | | ||
| 178 | | host | string | Hostname to connect to | | ||
| 179 | | port | int | Optional. Port number to connect to. Defaults to 1883. | | ||
| 180 | | keepalive | int | Optional. Number of sections after which the broker should PING the client if no messages have been recieved. | | ||
| 181 | | interface | string | Optional. The address or hostname of a local interface to bind to for this connection. | | ||
| 182 | |||
| 183 | #### disconnect | ||
| 184 | |||
| 185 | Disconnect from the broker. No parameters. | ||
| 186 | |||
| 187 | #### onConnect | ||
| 188 | |||
| 189 | Set the connect callback. This is called when the broker sends a CONNACK message in response to a connection. | ||
| 190 | |||
| 191 | | Parameter | Type | Description | | ||
| 192 | | --- | --- | ---- | | ||
| 193 | | callback | callback | The callback | | ||
| 194 | |||
| 195 | The callback should take parameters of the form: | ||
| 196 | |||
| 197 | | Parameter | Type | Description | | ||
| 198 | | --- | --- | ---- | | ||
| 199 | | rc | int | Response code from the broker. | | ||
| 200 | | message | string | String description of the response code. | | ||
| 201 | |||
| 202 | Response codes are as follows: | ||
| 203 | |||
| 204 | | Code | Meaning | | ||
| 205 | | --- | --- | | ||
| 206 | | 0 | Success | | ||
| 207 | | 1 | Connection refused (unacceptable protocol version) | | ||
| 208 | | 2 | Connection refused (identifier rejected) | | ||
| 209 | | 3 | Connection refused (broker unavailable ) | | ||
| 210 | | 4-255 | Reserved for future use | | ||
| 211 | |||
| 212 | #### onDisconnect | ||
| 213 | |||
| 214 | Set the disconnect callback. This is called when the broker has received the | ||
| 215 | DISCONNECT command and has disconnected the client. | ||
| 216 | |||
| 217 | | Parameter | Type | Description | | ||
| 218 | | --- | --- | ---- | | ||
| 219 | | callback | callback | The callback | | ||
| 220 | |||
| 221 | The callback should take parameters of the form: | ||
| 222 | |||
| 223 | | Parameter | Type | Description | | ||
| 224 | | --- | --- | ---- | | ||
| 225 | | rc | int | Reason for the disconnection. 0 means the client requested it. Any other value indicates an unexpected disconnection. | | ||
| 226 | |||
| 227 | #### onLog | ||
| 228 | |||
| 229 | Set the logging callback. | ||
| 230 | |||
| 231 | | Parameter | Type | Description | | ||
| 232 | | --- | --- | ---- | | ||
| 233 | | callback | callback | The callback | | ||
| 234 | |||
| 235 | The callback should take parameters of the form: | ||
| 236 | |||
| 237 | | Parameter | Type | Description | | ||
| 238 | | --- | --- | ---- | | ||
| 239 | | level | int | The log message level from the values below | | ||
| 240 | | str | string | The message string. | ||
| 241 | |||
| 242 | The level can be one of: | ||
| 243 | |||
| 244 | * Mosquitto\Client::LOG_DEBUG | ||
| 245 | * Mosquitto\Client::LOG_INFO | ||
| 246 | * Mosquitto\Client::LOG_NOTICE | ||
| 247 | * Mosquitto\Client::LOG_WARNING | ||
| 248 | * Mosquitto\Client::LOG_ERR | ||
| 249 | |||
| 250 | #### onSubscribe | ||
| 251 | |||
| 252 | Set the subscribe callback. This is called when the broker responds to | ||
| 253 | a subscription request. | ||
| 254 | |||
| 255 | | Parameter | Type | Description | | ||
| 256 | | --- | --- | ---- | | ||
| 257 | | callback | callback | The callback | | ||
| 258 | |||
| 259 | The callback should take parameters of the form: | ||
| 260 | |||
| 261 | | Parameter | Type | Description | | ||
| 262 | | --- | --- | ---- | | ||
| 263 | | mid | int | Message ID of the subscribe message | | ||
| 264 | | qos_count | int | Number of granted subscriptions | | ||
| 265 | |||
| 266 | This function needs to return the granted QoS for each subscription, but | ||
| 267 | currently cannot. | ||
| 268 | |||
| 269 | #### onUnsubscribe | ||
| 270 | |||
| 271 | Set the unsubscribe callback. This is called when the broker responds to | ||
| 272 | a unsubscribe request. | ||
| 273 | |||
| 274 | | Parameter | Type | Description | | ||
| 275 | | --- | --- | ---- | | ||
| 276 | | callback | callback | The callback | | ||
| 277 | |||
| 278 | The callback should take parameters of the form: | ||
| 279 | |||
| 280 | | Parameter | Type | Description | | ||
| 281 | | --- | --- | ---- | | ||
| 282 | | mid | int | Message ID of the unsubscribe message | | ||
| 283 | |||
| 284 | #### onMessage | ||
| 285 | |||
| 286 | Set the message callback. This is called when a message is received from the broker. | ||
| 287 | |||
| 288 | | Parameter | Type | Description | | ||
| 289 | | --- | --- | ---- | | ||
| 290 | | callback | callback | The callback | | ||
| 291 | |||
| 292 | The callback should take parameters of the form: | ||
| 293 | |||
| 294 | | Parameter | Type | Description | | ||
| 295 | | --- | --- | ---- | | ||
| 296 | | message | Mosquitto\Message | A Message object containing the message data | | ||
| 297 | |||
| 298 | |||
| 299 | #### setMaxInFlightMessages | ||
| 300 | |||
| 301 | Set the number of QoS 1 and 2 messages that can be โin flightโ at one time. An | ||
| 302 | in flight message is part way through its delivery flow. Attempts to send | ||
| 303 | further messages with publish() will result in the messages being queued until | ||
| 304 | the number of in flight messages reduces. | ||
| 305 | |||
| 306 | Set to 0 for no maximum. | ||
| 307 | |||
| 308 | | Parameter | Type | Description | | ||
| 309 | | --- | --- | ---- | | ||
| 310 | | max_inflight_messages | int | The maximum | | ||
| 311 | |||
| 312 | #### setMessageRetry | ||
| 313 | |||
| 314 | Set the number of seconds to wait before retrying messages. This applies to | ||
| 315 | publish messages with QoS>0. May be called at any time. | ||
| 316 | |||
| 317 | | Parameter | Type | Description | | ||
| 318 | | --- | --- | ---- | | ||
| 319 | | message_retry | int | The retry period | | ||
| 320 | |||
| 321 | #### publish | ||
| 322 | |||
| 323 | Publish a message on a given topic. | ||
| 324 | |||
| 325 | | Parameter | Type | Description | | ||
| 326 | | --- | --- | ---- | | ||
| 327 | | topic | string | The topic to publish on | | ||
| 328 | | payload | string | The message payload | | ||
| 329 | | qos | int | Integer value 0, 1 or 2 indicating the QoS for this message | | ||
| 330 | | retain | boolean | If true, make this message retained | | ||
| 331 | |||
| 332 | #### subscribe | ||
| 333 | |||
| 334 | Subscribe to a topic. | ||
| 335 | |||
| 336 | | Parameter | Type | Description | | ||
| 337 | | --- | --- | ---- | | ||
| 338 | | topic | string | The topic. | | ||
| 339 | | qos | The QoS to request for this subscription | | ||
| 340 | |||
| 341 | Returns the message ID of the subscription message, so this can be matched up | ||
| 342 | in the onSubscribe callback. | ||
| 343 | |||
| 344 | #### unsubscribe | ||
| 345 | |||
| 346 | Unsubscribe from a topic. | ||
| 347 | |||
| 348 | | Parameter | Type | Description | | ||
| 349 | | --- | --- | ---- | | ||
| 350 | | topic | string | The topic. | | ||
| 351 | | qos | The QoS to request for this subscription | | ||
| 352 | |||
| 353 | Returns the message ID of the subscription message, so this can be matched up | ||
| 354 | in the onUnsubscribe callback. | ||
| 355 | |||
| 356 | #### loop | ||
| 357 | |||
| 358 | The main network loop for the client. You must call this frequently in order | ||
| 359 | to keep communications between the client and broker working. If incoming data | ||
| 360 | is present it will then be processed. Outgoing commands, from e.g. publish(), | ||
| 361 | are normally sent immediately that their function is called, but this is not | ||
| 362 | always possible. loop() will also attempt to send any remaining outgoing | ||
| 363 | messages, which also includes commands that are part of the flow for messages | ||
| 364 | with QoS>0. | ||
| 365 | |||
| 366 | | Parameter | Type | Description | | ||
| 367 | | --- | --- | ---- | | ||
| 368 | | timeout | int | Optional. Number of milliseconds to wait for network activity. Pass 0 for instant timeout. Defaults to 1000. | | ||
| 369 | | max_packets | int | Currently unused. | | ||
| 370 | |||
| 371 | #### loopForever | ||
| 372 | |||
| 373 | Call loop() in an infinite blocking loop. Callbacks will be called as required. | ||
| 374 | This will handle reconnecting if the connection is lost. Call disconnect() in | ||
| 375 | a callback to return from the loop. | ||
| 376 | |||
| 377 | Note: exceptions thrown in callbacks do not currently cause the loop to exit. To work around this, use loop() and wrap your own loop structure around it such as a while(). | ||
| 378 | |||
| 379 | | Parameter | Type | Description | | ||
| 380 | | --- | --- | ---- | | ||
| 381 | | timeout | int | Optional. Number of milliseconds to wait for network activity. Pass 0 for instant timeout. Defaults to 1000. | | ||
| 382 | | max_packets | int | Currently unused. | | ||
| 383 | |||
| 384 | ### Class Mosquitto\Message | ||
| 385 | |||
| 386 | Represents a message received from a broker. All data is represented as | ||
| 387 | properties. | ||
| 388 | |||
| 389 | | Property | Type | Description | | ||
| 390 | | --- | --- | --- | | ||
| 391 | | topic | string | The topic this message was delivered to. | | ||
| 392 | | payload | string | The payload of this message. | | ||
| 393 | | mid | int | The ID of this message. | | ||
| 394 | | qos | int | The QoS value applied to this message. | | ||
| 395 | | retain | bool | Whether this is a retained message or not. | | ||
| 396 | |||
| 397 | This class has two static methods. | ||
| 398 | |||
| 399 | #### topicMatchesSub | ||
| 400 | |||
| 401 | Returns true if the supplied topic matches the supplied description, and | ||
| 402 | otherwise false. | ||
| 403 | |||
| 404 | | Parameter | Type | Description | | ||
| 405 | | --- | --- | ---- | | ||
| 406 | | topic | string | The topic to match | | ||
| 407 | | subscription | string | The subscription to match | | ||
| 408 | |||
| 409 | #### tokeniseTopic | ||
| 410 | |||
| 411 | Tokenise a topic or subscription string into an array of strings representing the topic hierarchy. | ||
| 412 | |||
| 413 | | Parameter | Type | Description | | ||
| 414 | | --- | --- | ---- | | ||
| 415 | | topic | string | The topic to tokenise | | ||
| 416 | |||
| 417 | ### Class Mosquitto\Exception | ||
| 418 | |||
| 419 | This is an exception that may be thrown by many of the operations in the Client | ||
| 420 | object. | ||
| 421 | |||
| 422 | ## To do | ||
| 423 | |||
| 424 | * Arginfo | ||
| 425 | * Logging callbacks | ||
| 426 | * TLS support | ||
| 427 | * Tests | ||
| 428 |
mosquitto_message.c
| File was created | 1 | #ifdef HAVE_CONFIG_H | |
| 2 | #include "config.h" | ||
| 3 | #endif | ||
| 4 | |||
| 5 | #include "php.h" | ||
| 6 | #include "php_ini.h" | ||
| 7 | #include "zend_variables.h" | ||
| 8 | #include "zend_exceptions.h" | ||
| 9 | #include "zend_API.h" | ||
| 10 | #include "ext/standard/info.h" | ||
| 11 | #include "php_mosquitto.h" | ||
| 12 | |||
| 13 | zend_class_entry *mosquitto_ce_message; | ||
| 14 | static zend_object_handlers mosquitto_message_object_handlers; | ||
| 15 | static HashTable php_mosquitto_message_properties; | ||
| 16 | |||
| 17 | /* {{{ Arginfo */ | ||
| 18 | |||
| 19 | ZEND_BEGIN_ARG_INFO(Mosquitto_Message_topicMatchesSub_args, ZEND_SEND_BY_VAL) | ||
| 20 | ZEND_ARG_INFO(0, topic) | ||
| 21 | ZEND_ARG_INFO(0, subscription) | ||
| 22 | ZEND_END_ARG_INFO() | ||
| 23 | |||
| 24 | ZEND_BEGIN_ARG_INFO(Mosquitto_Message_tokeniseTopic_args, ZEND_SEND_BY_VAL) | ||
| 25 | ZEND_ARG_INFO(0, topic) | ||
| 26 | ZEND_END_ARG_INFO() | ||
| 27 | |||
| 28 | /* }}} */ | ||
| 29 | |||
| 30 | PHP_METHOD(Mosquitto_Message, __construct) | ||
| 31 | { | ||
| 32 | PHP_MOSQUITTO_ERROR_HANDLING(); | ||
| 33 | if (zend_parse_parameters_none() == FAILURE) { | ||
| 34 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 35 | return; | ||
| 36 | } | ||
| 37 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 38 | } | ||
| 39 | |||
| 40 | /* {{{ Mosquitto\Message::topicMatchesSub() */ | ||
| 41 | PHP_METHOD(Mosquitto_Message, topicMatchesSub) | ||
| 42 | { | ||
| 43 | char *topic = NULL, *subscription = NULL; | ||
| 44 | int topic_len, subscription_len; | ||
| 45 | zend_bool result; | ||
| 46 | |||
| 47 | PHP_MOSQUITTO_ERROR_HANDLING(); | ||
| 48 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", | ||
| 49 | &topic, &topic_len, &subscription, &subscription_len) == FAILURE) { | ||
| 50 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 54 | |||
| 55 | mosquitto_topic_matches_sub(subscription, topic, (bool *) &result); | ||
| 56 | RETURN_BOOL(result); | ||
| 57 | } | ||
| 58 | /* }}} */ | ||
| 59 | |||
| 60 | /* {{{ Mosquitto\Message::tokeniseTopic() */ | ||
| 61 | PHP_METHOD(Mosquitto_Message, tokeniseTopic) | ||
| 62 | { | ||
| 63 | char *topic = NULL, **topics = NULL; | ||
| 64 | int topic_len = 0, retval = 0, count = 0, i = 0; | ||
| 65 | |||
| 66 | PHP_MOSQUITTO_ERROR_HANDLING(); | ||
| 67 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &topic, &topic_len) == FAILURE) { | ||
| 68 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | PHP_MOSQUITTO_RESTORE_ERRORS(); | ||
| 72 | |||
| 73 | retval = mosquitto_sub_topic_tokenise(topic, &topics, &count); | ||
| 74 | |||
| 75 | if (retval == MOSQ_ERR_NOMEM) { | ||
| 76 | zend_throw_exception_ex(mosquitto_ce_exception, 0 TSRMLS_CC, "Failed to tokenise topic"); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | array_init(return_value); | ||
| 81 | for (i = 0; i < count; i++) { | ||
| 82 | if (topics[i] == NULL) { | ||
| 83 | add_next_index_null(return_value); | ||
| 84 | } else { | ||
| 85 | add_next_index_string(return_value, topics[i], 1); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | mosquitto_sub_topic_tokens_free(&topics, count); | ||
| 90 | } | ||
| 91 | /* }}} */ | ||
| 92 | |||
| 93 | PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_READER_FUNCTION(mid); | ||
| 94 | PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_READER_FUNCTION(qos); | ||
| 95 | |||
| 96 | static int php_mosquitto_message_read_retain(mosquitto_message_object *mosquitto_object, zval **retval TSRMLS_DC) | ||
| 97 | { | ||
| 98 | MAKE_STD_ZVAL(*retval); | ||
| 99 | ZVAL_BOOL(*retval, mosquitto_object->message.retain); | ||
| 100 | return SUCCESS; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int php_mosquitto_message_read_topic(mosquitto_message_object *mosquitto_object, zval **retval TSRMLS_DC) | ||
| 104 | { | ||
| 105 | MAKE_STD_ZVAL(*retval); | ||
| 106 | |||
| 107 | if (mosquitto_object->message.topic != NULL) { | ||
| 108 | ZVAL_STRINGL(*retval, mosquitto_object->message.topic, strlen(mosquitto_object->message.topic), 1); | ||
| 109 | } else { | ||
| 110 | ZVAL_NULL(*retval); | ||
| 111 | } | ||
| 112 | |||
| 113 | return SUCCESS; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int php_mosquitto_message_read_payload(mosquitto_message_object *mosquitto_object, zval **retval TSRMLS_DC) | ||
| 117 | { | ||
| 118 | MAKE_STD_ZVAL(*retval); | ||
| 119 | ZVAL_STRINGL(*retval, mosquitto_object->message.payload, mosquitto_object->message.payloadlen, 1); | ||
| 120 | return SUCCESS; | ||
| 121 | } | ||
| 122 | |||
| 123 | PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_WRITER_FUNCTION(mid); | ||
| 124 | PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_WRITER_FUNCTION(qos); | ||
| 125 | |||
| 126 | static int php_mosquitto_message_write_retain(mosquitto_message_object *mosquitto_object, zval *newval TSRMLS_DC) | ||
| 127 | { | ||
| 128 | zval ztmp; | ||
| 129 | if (Z_TYPE_P(newval) != IS_BOOL) { | ||
| 130 | ztmp = *newval; | ||
| 131 | zval_copy_ctor(&ztmp); | ||
| 132 | convert_to_boolean(&ztmp); | ||
| 133 | newval = &ztmp; | ||
| 134 | } | ||
| 135 | |||
| 136 | mosquitto_object->message.retain = Z_LVAL_P(newval); | ||
| 137 | |||
| 138 | if (newval == &ztmp) { | ||
| 139 | zval_dtor(newval); | ||
| 140 | } | ||
| 141 | |||
| 142 | return SUCCESS; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int php_mosquitto_message_write_topic(mosquitto_message_object *mosquitto_object, zval *newval TSRMLS_DC) | ||
| 146 | { | ||
| 147 | zval ztmp; | ||
| 148 | if (Z_TYPE_P(newval) != IS_STRING) { | ||
| 149 | ztmp = *newval; | ||
| 150 | zval_copy_ctor(&ztmp); | ||
| 151 | convert_to_string(&ztmp); | ||
| 152 | newval = &ztmp; | ||
| 153 | } | ||
| 154 | |||
| 155 | if (mosquitto_object->message.topic && mosquitto_object->owned_topic) { | ||
| 156 | efree(mosquitto_object->message.topic); | ||
| 157 | } | ||
| 158 | |||
| 159 | mosquitto_object->message.topic = estrdup(Z_STRVAL_P(newval)); | ||
| 160 | mosquitto_object->owned_topic = 1; | ||
| 161 | |||
| 162 | if (newval == &ztmp) { | ||
| 163 | zval_dtor(newval); | ||
| 164 | } | ||
| 165 | |||
| 166 | return SUCCESS; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int php_mosquitto_message_write_payload(mosquitto_message_object *mosquitto_object, zval *newval TSRMLS_DC) | ||
| 170 | { | ||
| 171 | zval ztmp; | ||
| 172 | if (Z_TYPE_P(newval) != IS_STRING) { | ||
| 173 | ztmp = *newval; | ||
| 174 | zval_copy_ctor(&ztmp); | ||
| 175 | convert_to_string(&ztmp); | ||
| 176 | newval = &ztmp; | ||
| 177 | } | ||
| 178 | |||
| 179 | if (mosquitto_object->message.payload && mosquitto_object->owned_payload) { | ||
| 180 | efree(mosquitto_object->message.payload); | ||
| 181 | mosquitto_object->message.payloadlen = 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | mosquitto_object->message.payload = estrdup(Z_STRVAL_P(newval)); | ||
| 185 | mosquitto_object->message.payloadlen = Z_STRLEN_P(newval); | ||
| 186 | mosquitto_object->owned_payload = 1; | ||
| 187 | |||
| 188 | if (newval == &ztmp) { | ||
| 189 | zval_dtor(newval); | ||
| 190 | } | ||
| 191 | |||
| 192 | return SUCCESS; | ||
| 193 | } | ||
| 194 | |||
| 195 | const php_mosquitto_prop_handler php_mosquitto_message_property_entries[] = { | ||
| 196 | PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(mid), | ||
| 197 | PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(topic), | ||
| 198 | PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(payload), | ||
| 199 | PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(qos), | ||
| 200 | PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(retain), | ||
| 201 | {NULL, 0, NULL, NULL} | ||
| 202 | }; | ||
| 203 | |||
| 204 | zval *php_mosquitto_message_read_property(zval *object, zval *member, int type ZEND_LITERAL_KEY_DC TSRMLS_DC) | ||
| 205 | { | ||
| 206 | zval tmp_member; | ||
| 207 | zval *retval; | ||
| 208 | mosquitto_message_object *message_object; | ||
| 209 | php_mosquitto_prop_handler *hnd; | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | message_object = (mosquitto_message_object *) zend_object_store_get_object(object TSRMLS_CC); | ||
| 213 | |||
| 214 | if (Z_TYPE_P(member) != IS_STRING) { | ||
| 215 | tmp_member = *member; | ||
| 216 | zval_copy_ctor(&tmp_member); | ||
| 217 | convert_to_string(&tmp_member); | ||
| 218 | member = &tmp_member; | ||
| 219 | } | ||
| 220 | |||
| 221 | ret = zend_hash_find(&php_mosquitto_message_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); | ||
| 222 | |||
| 223 | if (ret == SUCCESS && hnd->read_func) { | ||
| 224 | ret = hnd->read_func(message_object, &retval TSRMLS_CC); | ||
| 225 | if (ret == SUCCESS) { | ||
| 226 | /* ensure we're creating a temporary variable */ | ||
| 227 | Z_SET_REFCOUNT_P(retval, 0); | ||
| 228 | } else { | ||
| 229 | retval = EG(uninitialized_zval_ptr); | ||
| 230 | } | ||
| 231 | } else { | ||
| 232 | zend_object_handlers * std_hnd = zend_get_std_object_handlers(); | ||
| 233 | retval = std_hnd->read_property(object, member, type ZEND_LITERAL_KEY_CC TSRMLS_CC); | ||
| 234 | } | ||
| 235 | |||
| 236 | if (member == &tmp_member) { | ||
| 237 | zval_dtor(member); | ||
| 238 | } | ||
| 239 | |||
| 240 | return(retval); | ||
| 241 | } | ||
| 242 | |||
| 243 | void php_mosquitto_message_write_property(zval *object, zval *member, zval *value ZEND_LITERAL_KEY_DC TSRMLS_DC) | ||
| 244 | { | ||
| 245 | zval tmp_member; | ||
| 246 | mosquitto_message_object *obj; | ||
| 247 | php_mosquitto_prop_handler *hnd; | ||
| 248 | int ret; | ||
| 249 | |||
| 250 | if (Z_TYPE_P(member) != IS_STRING) { | ||
| 251 | tmp_member = *member; | ||
| 252 | zval_copy_ctor(&tmp_member); | ||
| 253 | convert_to_string(&tmp_member); | ||
| 254 | member = &tmp_member; | ||
| 255 | } | ||
| 256 | |||
| 257 | ret = FAILURE; | ||
| 258 | obj = (mosquitto_message_object *)zend_objects_get_address(object TSRMLS_CC); | ||
| 259 | |||
| 260 | ret = zend_hash_find(&php_mosquitto_message_properties, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **) &hnd); | ||
| 261 | |||
| 262 | if (ret == SUCCESS && hnd->write_func) { | ||
| 263 | hnd->write_func(obj, value TSRMLS_CC); | ||
| 264 | if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) { | ||
| 265 | Z_ADDREF_P(value); | ||
| 266 | zval_ptr_dtor(&value); | ||
| 267 | } | ||
| 268 | } else { | ||
| 269 | zend_object_handlers * std_hnd = zend_get_std_object_handlers(); | ||
| 270 | std_hnd->write_property(object, member, value ZEND_LITERAL_KEY_CC TSRMLS_CC); | ||
| 271 | } | ||
| 272 | |||
| 273 | if (member == &tmp_member) { | ||
| 274 | zval_dtor(member); | ||
| 275 | } | ||
| 276 | } | ||
| 277 | |||
| 278 | static int php_mosquitto_message_has_property(zval *object, zval *member, int has_set_exists ZEND_LITERAL_KEY_DC TSRMLS_DC) | ||
| 279 | { | ||
| 280 | php_mosquitto_prop_handler *hnd; | ||
| 281 | int ret = 0; | ||
| 282 | |||
| 283 | if (zend_hash_find(&php_mosquitto_message_properties, Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, (void **)&hnd) == SUCCESS) { | ||
| 284 | switch (has_set_exists) { | ||
| 285 | case 2: | ||
| 286 | ret = 1; | ||
| 287 | break; | ||
| 288 | case 0: { | ||
| 289 | zval *value = php_mosquitto_message_read_property(object, member, BP_VAR_IS ZEND_LITERAL_KEY_CC TSRMLS_CC); | ||
| 290 | if (value != EG(uninitialized_zval_ptr)) { | ||
| 291 | ret = Z_TYPE_P(value) != IS_NULL? 1:0; | ||
| 292 | /* refcount is 0 */ | ||
| 293 | Z_ADDREF_P(value); | ||
| 294 | zval_ptr_dtor(&value); | ||
| 295 | } | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | default: { | ||
| 299 | zval *value = php_mosquitto_message_read_property(object, member, BP_VAR_IS ZEND_LITERAL_KEY_CC TSRMLS_CC); | ||
| 300 | if (value != EG(uninitialized_zval_ptr)) { | ||
| 301 | convert_to_boolean(value); | ||
| 302 | ret = Z_BVAL_P(value)? 1:0; | ||
| 303 | /* refcount is 0 */ | ||
| 304 | Z_ADDREF_P(value); | ||
| 305 | zval_ptr_dtor(&value); | ||
| 306 | } | ||
| 307 | break; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | } else { | ||
| 311 | zend_object_handlers * std_hnd = zend_get_std_object_handlers(); | ||
| 312 | ret = std_hnd->has_property(object, member, has_set_exists ZEND_LITERAL_KEY_CC TSRMLS_CC); | ||
| 313 | } | ||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | |||
| 317 | static HashTable *php_mosquitto_message_get_properties(zval *object TSRMLS_DC) | ||
| 318 | { | ||
| 319 | mosquitto_message_object *obj; | ||
| 320 | php_mosquitto_prop_handler *hnd; | ||
| 321 | HashTable *props; | ||
| 322 | zval *val; | ||
| 323 | char *key; | ||
| 324 | uint key_len; | ||
| 325 | HashPosition pos; | ||
| 326 | ulong num_key; | ||
| 327 | |||
| 328 | obj = (mosquitto_message_object *)zend_objects_get_address(object TSRMLS_CC); | ||
| 329 | props = zend_std_get_properties(object TSRMLS_CC); | ||
| 330 | |||
| 331 | zend_hash_internal_pointer_reset_ex(&php_mosquitto_message_properties, &pos); | ||
| 332 | |||
| 333 | while (zend_hash_get_current_data_ex(&php_mosquitto_message_properties, (void**)&hnd, &pos) == SUCCESS) { | ||
| 334 | zend_hash_get_current_key_ex(&php_mosquitto_message_properties, &key, &key_len, &num_key, 0, &pos); | ||
| 335 | if (!hnd->read_func || hnd->read_func(obj, &val TSRMLS_CC) != SUCCESS) { | ||
| 336 | val = EG(uninitialized_zval_ptr); | ||
| 337 | Z_ADDREF_P(val); | ||
| 338 | } | ||
| 339 | zend_hash_update(props, key, key_len, (void *)&val, sizeof(zval *), NULL); | ||
| 340 | zend_hash_move_forward_ex(&php_mosquitto_message_properties, &pos); | ||
| 341 | } | ||
| 342 | return obj->std.properties; | ||
| 343 | } | ||
| 344 | |||
| 345 | |||
| 346 | void php_mosquitto_message_add_property(HashTable *h, const char *name, size_t name_length, php_mosquitto_read_t read_func, php_mosquitto_write_t write_func TSRMLS_DC) | ||
| 347 | { | ||
| 348 | php_mosquitto_prop_handler p; | ||
| 349 | |||
| 350 | p.name = (char*) name; | ||
| 351 | p.name_length = name_length; | ||
| 352 | p.read_func = (read_func) ? read_func : NULL; | ||
| 353 | p.write_func = (write_func) ? write_func : NULL; | ||
| 354 | zend_hash_add(h, (char *)name, name_length + 1, &p, sizeof(php_mosquitto_prop_handler), NULL); | ||
| 355 | } | ||
| 356 | |||
| 357 | static void mosquitto_message_object_destroy(void *object TSRMLS_DC) | ||
| 358 | { | ||
| 359 | mosquitto_message_object *message = (mosquitto_message_object *) object; | ||
| 360 | zend_hash_destroy(message->std.properties); | ||
| 361 | FREE_HASHTABLE(message->std.properties); | ||
| 362 | |||
| 363 | if (message->owned_topic == 1) { | ||
| 364 | efree(message->message.topic); | ||
| 365 | } | ||
| 366 | |||
| 367 | if (message->owned_payload == 1) { | ||
| 368 | efree(message->message.payload); | ||
| 369 | } | ||
| 370 | |||
| 371 | efree(object); | ||
| 372 | } | ||
| 373 | |||
| 374 | static zend_object_value mosquitto_message_object_new(zend_class_entry *ce TSRMLS_DC) { | ||
| 375 | |||
| 376 | zend_object_value retval; | ||
| 377 | mosquitto_message_object *message_obj; | ||
| 378 | #if PHP_VERSION_ID < 50399 | ||
| 379 | zval *temp; | ||
| 380 | #endif | ||
| 381 | |||
| 382 | message_obj = ecalloc(1, sizeof(mosquitto_message_object)); | ||
| 383 | message_obj->std.ce = ce; | ||
| 384 | |||
| 385 | #ifdef ZTS | ||
| 386 | message_obj->TSRMLS_C = TSRMLS_C; | ||
| 387 | #endif | ||
| 388 | |||
| 389 | ALLOC_HASHTABLE(message_obj->std.properties); | ||
| 390 | zend_hash_init(message_obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); | ||
| 391 | #if PHP_VERSION_ID < 50399 | ||
| 392 | zend_hash_copy(message_obj->std.properties, &mosquitto_ce_message->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &temp, sizeof(zval *)); | ||
| 393 | #else | ||
| 394 | object_properties_init(&message_obj->std, mosquitto_ce_message); | ||
| 395 | #endif | ||
| 396 | retval.handle = zend_objects_store_put(message_obj, NULL, (zend_objects_free_object_storage_t) mosquitto_message_object_destroy, NULL TSRMLS_CC); | ||
| 397 | retval.handlers = &mosquitto_message_object_handlers; | ||
| 398 | return retval; | ||
| 399 | } | ||
| 400 | |||
| 401 | const zend_function_entry mosquitto_message_methods[] = { | ||
| 402 | PHP_ME(Mosquitto_Message, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) | ||
| 403 | PHP_ME(Mosquitto_Message, topicMatchesSub, Mosquitto_Message_topicMatchesSub_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) | ||
| 404 | PHP_ME(Mosquitto_Message, tokeniseTopic, Mosquitto_Message_tokeniseTopic_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) | ||
| 405 | PHP_FE_END | ||
| 406 | }; | ||
| 407 | |||
| 408 | PHP_MINIT_FUNCTION(mosquitto_message) | ||
| 409 | { | ||
| 410 | zend_class_entry message_ce; | ||
| 411 | memcpy(&mosquitto_message_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); | ||
| 412 | mosquitto_message_object_handlers.read_property = php_mosquitto_message_read_property; | ||
| 413 | mosquitto_message_object_handlers.write_property = php_mosquitto_message_write_property; | ||
| 414 | mosquitto_message_object_handlers.has_property = php_mosquitto_message_has_property; | ||
| 415 | mosquitto_message_object_handlers.get_properties = php_mosquitto_message_get_properties; | ||
| 416 | |||
| 417 | INIT_NS_CLASS_ENTRY(message_ce, "Mosquitto", "Message", mosquitto_message_methods); | ||
| 418 | mosquitto_ce_message = zend_register_internal_class(&message_ce TSRMLS_CC); | ||
| 419 | mosquitto_ce_message->create_object = mosquitto_message_object_new; | ||
| 420 | |||
| 421 | zend_hash_init(&php_mosquitto_message_properties, 0, NULL, NULL, 1); | ||
| 422 | PHP_MOSQUITTO_ADD_PROPERTIES(&php_mosquitto_message_properties, php_mosquitto_message_property_entries); | ||
| 423 | |||
| 424 | return SUCCESS; | ||
| 425 | } | ||
| 426 |
package.xml
| File was created | 1 | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | <package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.7" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> | ||
| 3 | <name>Mosquitto</name> | ||
| 4 | <channel>pecl.mgdm.net</channel> | ||
| 5 | <summary>Extension for libmosquitto</summary> | ||
| 6 | <description>Mosquitto provides support for the MQTT protocol, including publishing, subscribing, and an event loop.</description> | ||
| 7 | <lead> | ||
| 8 | <name>Michael Maclean</name> | ||
| 9 | <user>mgdm</user> | ||
| 10 | <email>mgdm@php.net</email> | ||
| 11 | <active>yes</active> | ||
| 12 | </lead> | ||
| 13 | |||
| 14 | <date>2014-04-28</date> | ||
| 15 | <version><release>0.2.2</release><api>0.2.0</api></version> | ||
| 16 | <stability><release>alpha</release><api>alpha</api></stability> | ||
| 17 | <license uri="http://opensource.org/licenses/BSD-3-Clause">BSD 3-Clause License</license> | ||
| 18 | <notes> | ||
| 19 | * Add missing unsubscribe method | ||
| 20 | </notes> | ||
| 21 | |||
| 22 | <contents> | ||
| 23 | <dir name="/"> | ||
| 24 | <file role="doc" name="README.md"/> | ||
| 25 | <file role="doc" name="CREDITS"/> | ||
| 26 | <file role="doc" name="LICENSE"/> | ||
| 27 | |||
| 28 | <file role="src" name="php_mosquitto.h"/> | ||
| 29 | |||
| 30 | <file role="src" name="mosquitto.c"/> | ||
| 31 | <file role="src" name="mosquitto_message.c"/> | ||
| 32 | |||
| 33 | <file role="src" name="config.m4"/> | ||
| 34 | <file role="src" name="config.w32"/> | ||
| 35 | </dir> | ||
| 36 | </contents> | ||
| 37 | |||
| 38 | <dependencies> | ||
| 39 | <required> | ||
| 40 | <php> | ||
| 41 | <min>5.3.0</min> | ||
| 42 | </php> | ||
| 43 | <pearinstaller> | ||
| 44 | <min>1.4.0</min> | ||
| 45 | </pearinstaller> | ||
| 46 | </required> | ||
| 47 | |||
| 48 | </dependencies> | ||
| 49 | |||
| 50 | <providesextension>mosquitto</providesextension> | ||
| 51 | |||
| 52 | <extsrcrelease> | ||
| 53 | <configureoption default="autodetect" name="with-mosquitto" prompt="Please provide the prefix of the libmosquitto installation" /> | ||
| 54 | </extsrcrelease> | ||
| 55 | |||
| 56 | <changelog> | ||
| 57 | </changelog> | ||
| 58 | </package> | ||
| 59 | <!-- | ||
| 60 | vim:et:ts=1:sw=1 | ||
| 61 | --> | ||
| 62 |
php_mosquitto.h
| File was created | 1 | #ifndef PHP_MOSQUITTO_H | |
| 2 | #define PHP_MOSQUITTO_H | ||
| 3 | |||
| 4 | #define PHP_MOSQUITTO_VERSION "0.2.2" | ||
| 5 | |||
| 6 | extern zend_module_entry mosquitto_module_entry; | ||
| 7 | #define phpext_mosquitto_ptr &mosquitto_module_entry | ||
| 8 | |||
| 9 | #ifdef PHP_WIN32 | ||
| 10 | # define PHP_MOSQUITTO_API __declspec(dllexport) | ||
| 11 | #elif defined(__GNUC__) && __GNUC__ >= 4 | ||
| 12 | # define PHP_MOSQUITTO_API __attribute__ ((visibility("default"))) | ||
| 13 | #else | ||
| 14 | # define PHP_MOSQUITTO_API | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifdef __GLIBC__ | ||
| 18 | #define POSSIBLY_UNUSED __attribute__((unused)) | ||
| 19 | #else | ||
| 20 | #define POSSIBLY_UNUSED | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #if defined(PHP_VERSION_ID) && (PHP_VERSION_ID >= 50399) | ||
| 24 | # define ZEND_LITERAL_KEY_DC , const zend_literal *_zend_literal_key | ||
| 25 | # define ZEND_LITERAL_KEY_CC , _zend_literal_key | ||
| 26 | # define ZEND_LITERAL_NIL_CC , NULL | ||
| 27 | #else | ||
| 28 | # define ZEND_LITERAL_KEY_DC | ||
| 29 | # define ZEND_LITERAL_KEY_CC | ||
| 30 | # define ZEND_LITERAL_NIL_CC | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #ifdef ZTS | ||
| 34 | #include "TSRM.h" | ||
| 35 | #endif | ||
| 36 | |||
| 37 | #include <mosquitto.h> | ||
| 38 | |||
| 39 | typedef struct _mosquitto_client_object { | ||
| 40 | zend_object std; | ||
| 41 | struct mosquitto *client; | ||
| 42 | |||
| 43 | zend_fcall_info connect_callback; | ||
| 44 | zend_fcall_info_cache connect_callback_cache; | ||
| 45 | zend_fcall_info subscribe_callback; | ||
| 46 | zend_fcall_info_cache subscribe_callback_cache; | ||
| 47 | zend_fcall_info unsubscribe_callback; | ||
| 48 | zend_fcall_info_cache unsubscribe_callback_cache; | ||
| 49 | zend_fcall_info message_callback; | ||
| 50 | zend_fcall_info_cache message_callback_cache; | ||
| 51 | zend_fcall_info disconnect_callback; | ||
| 52 | zend_fcall_info_cache disconnect_callback_cache; | ||
| 53 | zend_fcall_info log_callback; | ||
| 54 | zend_fcall_info_cache log_callback_cache; | ||
| 55 | |||
| 56 | int looping; | ||
| 57 | |||
| 58 | #ifdef ZTS | ||
| 59 | TSRMLS_D; | ||
| 60 | #endif | ||
| 61 | } mosquitto_client_object; | ||
| 62 | |||
| 63 | typedef struct _mosquitto_message_object { | ||
| 64 | zend_object std; | ||
| 65 | struct mosquitto_message message; | ||
| 66 | zend_bool owned_topic; | ||
| 67 | zend_bool owned_payload; | ||
| 68 | #ifdef ZTS | ||
| 69 | TSRMLS_D; | ||
| 70 | #endif | ||
| 71 | } mosquitto_message_object; | ||
| 72 | |||
| 73 | typedef int (*php_mosquitto_read_t)(mosquitto_message_object *mosquitto_object, zval **retval TSRMLS_DC); | ||
| 74 | typedef int (*php_mosquitto_write_t)(mosquitto_message_object *mosquitto_object, zval *newval TSRMLS_DC); | ||
| 75 | |||
| 76 | typedef struct _php_mosquitto_prop_handler { | ||
| 77 | const char *name; | ||
| 78 | size_t name_length; | ||
| 79 | php_mosquitto_read_t read_func; | ||
| 80 | php_mosquitto_write_t write_func; | ||
| 81 | } php_mosquitto_prop_handler; | ||
| 82 | |||
| 83 | |||
| 84 | #define PHP_MOSQUITTO_ERROR_HANDLING() \ | ||
| 85 | zend_replace_error_handling(EH_THROW, mosquitto_ce_exception, &MQTTG(mosquitto_original_error_handling) TSRMLS_CC) | ||
| 86 | |||
| 87 | #define PHP_MOSQUITTO_RESTORE_ERRORS() \ | ||
| 88 | zend_restore_error_handling(&MQTTG(mosquitto_original_error_handling) TSRMLS_CC) | ||
| 89 | |||
| 90 | |||
| 91 | #define PHP_MOSQUITTO_FREE_CALLBACK(CALLBACK) \ | ||
| 92 | if (ZEND_FCI_INITIALIZED(client->CALLBACK ## _callback)) { \ | ||
| 93 | zval_ptr_dtor(&client->CALLBACK ## _callback.function_name); \ | ||
| 94 | } \ | ||
| 95 | \ | ||
| 96 | if (client->CALLBACK ## _callback.object_ptr != NULL) { \ | ||
| 97 | zval_ptr_dtor(&client->CALLBACK ## _callback.object_ptr); \ | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 101 | #define PHP_MOSQUITTO_MESSAGE_PROPERTY_ENTRY_RECORD(name) \ | ||
| 102 | { "" #name "", sizeof("" #name "") - 1, php_mosquitto_message_read_##name, php_mosquitto_message_write_##name } | ||
| 103 | |||
| 104 | #define PHP_MOSQUITTO_ADD_PROPERTIES(a, b) \ | ||
| 105 | { \ | ||
| 106 | int i = 0; \ | ||
| 107 | while (b[i].name != NULL) { \ | ||
| 108 | php_mosquitto_message_add_property((a), (b)[i].name, (b)[i].name_length, \ | ||
| 109 | (php_mosquitto_read_t)(b)[i].read_func, (php_mosquitto_write_t)(b)[i].write_func TSRMLS_CC); \ | ||
| 110 | i++; \ | ||
| 111 | } \ | ||
| 112 | } | ||
| 113 | |||
| 114 | #define PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_READER_FUNCTION(name) \ | ||
| 115 | static int php_mosquitto_message_read_##name(mosquitto_message_object *mosquitto_object, zval **retval TSRMLS_DC) \ | ||
| 116 | { \ | ||
| 117 | MAKE_STD_ZVAL(*retval); \ | ||
| 118 | ZVAL_LONG(*retval, mosquitto_object->message.name); \ | ||
| 119 | return SUCCESS; \ | ||
| 120 | } | ||
| 121 | |||
| 122 | #define PHP_MOSQUITTO_MESSAGE_LONG_PROPERTY_WRITER_FUNCTION(name) \ | ||
| 123 | static int php_mosquitto_message_write_##name(mosquitto_message_object *mosquitto_object, zval *newval TSRMLS_DC) \ | ||
| 124 | { \ | ||
| 125 | zval ztmp; \ | ||
| 126 | if (Z_TYPE_P(newval) != IS_LONG) { \ | ||
| 127 | ztmp = *newval; \ | ||
| 128 | zval_copy_ctor(&ztmp); \ | ||
| 129 | convert_to_long(&ztmp); \ | ||
| 130 | newval = &ztmp; \ | ||
| 131 | } \ | ||
| 132 | \ | ||
| 133 | mosquitto_object->message.name = Z_LVAL_P(newval); \ | ||
| 134 | \ | ||
| 135 | if (newval == &ztmp) { \ | ||
| 136 | zval_dtor(newval); \ | ||
| 137 | } \ | ||
| 138 | return SUCCESS; \ | ||
| 139 | } | ||
| 140 | |||
| 141 | ZEND_BEGIN_MODULE_GLOBALS(mosquitto) | ||
| 142 | char *client_key; | ||
| 143 | int client_key_len; | ||
| 144 | zend_object_handlers mosquitto_std_object_handlers; | ||
| 145 | zend_error_handling mosquitto_original_error_handling; | ||
| 146 | ZEND_END_MODULE_GLOBALS(mosquitto) | ||
| 147 | |||
| 148 | #ifdef ZTS | ||
| 149 | # define MQTTG(v) TSRMG(mosquitto_globals_id, zend_mosquitto_globals *, v) | ||
| 150 | #else | ||
| 151 | # define MQTTG(v) (mosquitto_globals.v) | ||
| 152 | #endif | ||
| 153 | |||
| 154 | ZEND_EXTERN_MODULE_GLOBALS(mosquitto) | ||
| 155 | |||
| 156 | extern zend_class_entry *mosquitto_ce_exception; | ||
| 157 | extern zend_class_entry *mosquitto_ce_client; | ||
| 158 | extern zend_class_entry *mosquitto_ce_message; | ||
| 159 | |||
| 160 | PHP_MOSQUITTO_API void php_mosquitto_connect_callback(struct mosquitto *mosq, void *obj, int rc); | ||
| 161 | PHP_MOSQUITTO_API void php_mosquitto_disconnect_callback(struct mosquitto *mosq, void *obj, int rc); | ||
| 162 | PHP_MOSQUITTO_API void php_mosquitto_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str); | ||
| 163 | PHP_MOSQUITTO_API void php_mosquitto_message_callback(struct mosquitto *mosq, void *client_obj, const struct mosquitto_message *message); | ||
| 164 | PHP_MOSQUITTO_API void php_mosquitto_subscribe_callback(struct mosquitto *mosq, void *client_obj, int mid, int qos_count, const int *granted_qos); | ||
| 165 | PHP_MOSQUITTO_API void php_mosquitto_unsubscribe_callback(struct mosquitto *mosq, void *client_obj, int mid); | ||
| 166 | PHP_MOSQUITTO_API void php_mosquitto_disconnect_callback(struct mosquitto *mosq, void *obj, int rc); | ||
| 167 | |||
| 168 | PHP_MOSQUITTO_API char *php_mosquitto_strerror_wrapper(int err); | ||
| 169 | void php_mosquitto_handle_errno(int retval, int err TSRMLS_DC); | ||
| 170 | void php_mosquitto_exit_loop(mosquitto_client_object *object); | ||
| 171 | |||
| 172 | PHP_MINIT_FUNCTION(mosquitto); | ||
| 173 | PHP_MINIT_FUNCTION(mosquitto_message); | ||
| 174 | PHP_MSHUTDOWN_FUNCTION(mosquitto); | ||
| 175 | PHP_MINFO_FUNCTION(mosquitto); | ||
| 176 | |||
| 177 | #endif /* PHP_MOSQUITTO_H */ | ||
| 178 | |||
| 179 | /* __footer_here__ */ | ||
| 180 |