void OnRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle); // tcp handle jerry_value_t jtcp = iotjs_tcpwrap_jobject(tcp_wrap); // socket object jerry_value_t jsocket = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_OWNER); IOTJS_ASSERT(jerry_value_is_object(jsocket)); // onread callback jerry_value_t jonread = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONREAD); IOTJS_ASSERT(jerry_value_is_function(jonread)); iotjs_jargs_t jargs = iotjs_jargs_create(4); iotjs_jargs_append_jval(&jargs, jsocket); iotjs_jargs_append_number(&jargs, nread); iotjs_jargs_append_bool(&jargs, false); if (nread <= 0) { if (buf->base != NULL) { iotjs_buffer_release(buf->base); } if (nread < 0) { if (nread == UV__EOF) { iotjs_jargs_replace(&jargs, 2, jerry_create_boolean(true)); } iotjs_make_callback(jonread, jerry_create_undefined(), &jargs); } } else { jerry_value_t jbuffer = iotjs_bufferwrap_create_buffer((size_t)nread); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); iotjs_bufferwrap_copy(buffer_wrap, buf->base, (size_t)nread); iotjs_jargs_append_jval(&jargs, jbuffer); iotjs_make_callback(jonread, jerry_create_undefined(), &jargs); jerry_release_value(jbuffer); iotjs_buffer_release(buf->base); } iotjs_jargs_destroy(&jargs); jerry_release_value(jonread); jerry_release_value(jsocket); }
// Call onWrite and callback after ClientRequest._write void iotjs_https_call_read_onwrite(uv_timer_t* timer) { iotjs_https_t* https_data = (iotjs_https_t*)(timer->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); uv_timer_stop(&(_this->async_read_onwrite)); if (iotjs_jval_is_null(&_this->jthis_native)) return; const iotjs_jargs_t* jarg = iotjs_jargs_get_empty(); const iotjs_jval_t* jthis = &(_this->jthis_native); IOTJS_ASSERT(iotjs_jval_is_function(&(_this->read_onwrite))); if (!iotjs_jval_is_undefined(&(_this->read_callback))) iotjs_make_callback(&(_this->read_callback), jthis, jarg); iotjs_make_callback(&(_this->read_onwrite), jthis, jarg); }
// Call any property of ClientRequest._Incoming bool iotjs_https_jcallback(iotjs_https_t* https_data, const char* property, const iotjs_jargs_t* jarg, bool resultvalue) { iotjs_jval_t* jthis = iotjs_https_jthis_from_https(https_data); bool retval = true; if (iotjs_jval_is_null(jthis)) return retval; iotjs_jval_t jincoming = iotjs_jval_get_property(jthis, IOTJS_MAGIC_STRING__INCOMING); iotjs_jval_t cb = iotjs_jval_get_property(&jincoming, property); IOTJS_ASSERT(iotjs_jval_is_function(&cb)); if (!resultvalue) { iotjs_make_callback(&cb, &jincoming, jarg); } else { iotjs_jval_t result = iotjs_make_callback_with_result(&cb, &jincoming, jarg); retval = iotjs_jval_as_boolean(&result); iotjs_jval_destroy(&result); } iotjs_jval_destroy(&jincoming); iotjs_jval_destroy(&cb); return retval; }
// Cleanup before destructor void iotjs_https_cleanup(iotjs_https_t* https_data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); _this->loop = NULL; uv_close((uv_handle_t*)&_this->timeout, (uv_close_cb)iotjs_https_uv_close_callback); uv_close((uv_handle_t*)&_this->socket_timeout, (uv_close_cb)iotjs_https_uv_close_callback); uv_close((uv_handle_t*)&_this->async_read_onwrite, (uv_close_cb)iotjs_https_uv_close_callback); iotjs_https_jcallback(https_data, IOTJS_MAGIC_STRING_ONEND, iotjs_jargs_get_empty(), false); iotjs_https_jcallback(https_data, IOTJS_MAGIC_STRING_ONCLOSED, iotjs_jargs_get_empty(), false); curl_multi_remove_handle(_this->curl_multi_handle, _this->curl_easy_handle); curl_easy_cleanup(_this->curl_easy_handle); _this->curl_easy_handle = NULL; curl_multi_cleanup(_this->curl_multi_handle); _this->curl_multi_handle = NULL; curl_slist_free_all(_this->header_list); if (_this->poll_data != NULL) iotjs_https_poll_close_all(_this->poll_data); if (_this->to_destroy_read_onwrite) { const iotjs_jargs_t* jarg = iotjs_jargs_get_empty(); const iotjs_jval_t* jthis = &(_this->jthis_native); IOTJS_ASSERT(iotjs_jval_is_function(&(_this->read_onwrite))); if (!iotjs_jval_is_undefined(&(_this->read_callback))) iotjs_make_callback(&(_this->read_callback), jthis, jarg); iotjs_make_callback(&(_this->read_onwrite), jthis, jarg); _this->to_destroy_read_onwrite = false; iotjs_string_destroy(&(_this->read_chunk)); iotjs_jval_destroy(&(_this->read_onwrite)); iotjs_jval_destroy(&(_this->read_callback)); } return; }
// A client socket wants to connect to this server. // Parameters: // * uv_stream_t* handle - server handle // * int status - status code static void OnConnection(uv_stream_t* handle, int status) { // Server tcp wrapper. iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle); // Tcp object jerry_value_t jtcp = iotjs_tcpwrap_jobject(tcp_wrap); // `onconnection` callback. jerry_value_t jonconnection = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONCONNECTION); IOTJS_ASSERT(jerry_value_is_function(jonconnection)); // The callback takes two parameter // [0] status // [1] client tcp object iotjs_jargs_t args = iotjs_jargs_create(2); iotjs_jargs_append_number(&args, status); if (status == 0) { // Create client socket handle wrapper. jerry_value_t jcreate_tcp = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_CREATETCP); IOTJS_ASSERT(jerry_value_is_function(jcreate_tcp)); jerry_value_t jclient_tcp = iotjs_jhelper_call_ok(jcreate_tcp, jerry_create_undefined(), iotjs_jargs_get_empty()); IOTJS_ASSERT(jerry_value_is_object(jclient_tcp)); iotjs_tcpwrap_t* tcp_wrap_client = (iotjs_tcpwrap_t*)(iotjs_jval_get_object_native_handle(jclient_tcp)); uv_stream_t* client_handle = (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap_client)); int err = uv_accept(handle, client_handle); if (err) { iotjs_jargs_destroy(&args); return; } iotjs_jargs_append_jval(&args, jclient_tcp); jerry_release_value(jcreate_tcp); jerry_release_value(jclient_tcp); } iotjs_make_callback(jonconnection, jtcp, &args); jerry_release_value(jonconnection); iotjs_jargs_destroy(&args); }
// Socket close result handler. void AfterClose(uv_handle_t* handle) { iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_handle(handle); // tcp object. jerry_value_t jtcp = iotjs_handlewrap_jobject(wrap); // callback function. jerry_value_t jcallback = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONCLOSE); if (jerry_value_is_function(jcallback)) { iotjs_make_callback(jcallback, jerry_create_undefined(), iotjs_jargs_get_empty()); } jerry_release_value(jcallback); }
static void iotjs_adc_after_work(uv_work_t* work_req, int status) { iotjs_adc_reqwrap_t* req_wrap = iotjs_adc_reqwrap_from_request(work_req); iotjs_adc_reqdata_t* req_data = iotjs_adc_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); bool result = req_data->result; if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kAdcOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to open ADC device"); } else { iotjs_jargs_append_null(&jargs); } break; case kAdcOpRead: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot read from ADC device"); } else { iotjs_jargs_append_null(&jargs); iotjs_jargs_append_number(&jargs, req_data->value); } break; case kAdcOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot close ADC device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_adc_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_adc_reqwrap_dispatched(req_wrap); }
static void AfterShutdown(uv_shutdown_t* req, int status) { iotjs_shutdown_reqwrap_t* req_wrap = (iotjs_shutdown_reqwrap_t*)(req->data); iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(tcp_wrap != NULL); // function onShutdown(status) jerry_value_t jonshutdown = iotjs_shutdown_reqwrap_jcallback(req_wrap); IOTJS_ASSERT(jerry_value_is_function(jonshutdown)); iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); iotjs_make_callback(jonshutdown, jerry_create_undefined(), &args); iotjs_jargs_destroy(&args); iotjs_shutdown_reqwrap_dispatched(req_wrap); }
void AfterWrite(uv_write_t* req, int status) { iotjs_write_reqwrap_t* req_wrap = (iotjs_write_reqwrap_t*)(req->data); iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(tcp_wrap != NULL); // Take callback function object. jerry_value_t jcallback = iotjs_write_reqwrap_jcallback(req_wrap); // Only parameter is status code. iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); // Make callback. iotjs_make_callback(jcallback, jerry_create_undefined(), &args); // Destroy args iotjs_jargs_destroy(&args); // Release request wrapper. iotjs_write_reqwrap_dispatched(req_wrap); }
// Connection request result handler. static void AfterConnect(uv_connect_t* req, int status) { iotjs_connect_reqwrap_t* req_wrap = (iotjs_connect_reqwrap_t*)(req->data); IOTJS_ASSERT(req_wrap != NULL); // Take callback function object. // function afterConnect(status) jerry_value_t jcallback = iotjs_connect_reqwrap_jcallback(req_wrap); IOTJS_ASSERT(jerry_value_is_function(jcallback)); // Only parameter is status code. iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); // Make callback. iotjs_make_callback(jcallback, jerry_create_undefined(), &args); // Destroy args iotjs_jargs_destroy(&args); // Release request wrapper. iotjs_connect_reqwrap_dispatched(req_wrap); }
static void iotjs_spi_after_work(uv_work_t* work_req, int status) { iotjs_spi_reqwrap_t* req_wrap = iotjs_spi_reqwrap_from_request(work_req); iotjs_spi_reqdata_t* req_data = iotjs_spi_reqwrap_data(req_wrap); iotjs_spi_t* spi = iotjs_spi_instance_from_reqwrap(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); bool result = req_data->result; if (status) { iotjs_jargs_append_error(&jargs, "System error"); } else { switch (req_data->op) { case kSpiOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to export SPI device"); } else { iotjs_jargs_append_null(&jargs); } break; case kSpiOpTransferArray: case kSpiOpTransferBuffer: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot transfer from SPI device"); } else { iotjs_jargs_append_null(&jargs); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); // Append read data iotjs_jval_t result_data = iotjs_jval_create_byte_array(_this->buf_len, _this->rx_buf_data); iotjs_jargs_append_jval(&jargs, &result_data); iotjs_jval_destroy(&result_data); } if (req_data->op == kSpiOpTransferArray) iotjs_spi_release_buffer(spi); break; case kSpiOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to unexport SPI device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_spi_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_spi_reqwrap_dispatched(req_wrap); }
static void iotjs_pwm_after_worker(uv_work_t* work_req, int status) { iotjs_pwm_reqwrap_t* req_wrap = iotjs_pwm_reqwrap_from_request(work_req); iotjs_pwm_reqdata_t* req_data = iotjs_pwm_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(1); bool result = req_data->result; if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kPwmOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to open PWM device"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetDutyCycle: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set duty-cycle"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetPeriod: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set period"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetEnable: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set enable"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot close PWM device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_pwm_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_pwm_reqwrap_dispatched(req_wrap); }
static void AfterAsync(uv_fs_t* req) { iotjs_fs_reqwrap_t* req_wrap = (iotjs_fs_reqwrap_t*)(req->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(&req_wrap->req == req); const jerry_value_t cb = iotjs_reqwrap_jcallback(&req_wrap->reqwrap); IOTJS_ASSERT(jerry_value_is_function(cb)); iotjs_jargs_t jarg = iotjs_jargs_create(2); if (req->result < 0) { jerry_value_t jerror = iotjs_create_uv_exception(req->result, "open"); iotjs_jargs_append_jval(&jarg, jerror); jerry_release_value(jerror); } else { iotjs_jargs_append_null(&jarg); switch (req->fs_type) { case UV_FS_CLOSE: { break; } case UV_FS_OPEN: case UV_FS_READ: case UV_FS_WRITE: { iotjs_jargs_append_number(&jarg, (double)req->result); break; } case UV_FS_SCANDIR: { int r; uv_dirent_t ent; uint32_t idx = 0; jerry_value_t ret = jerry_create_array(0); while ((r = uv_fs_scandir_next(req, &ent)) != UV_EOF) { jerry_value_t name = jerry_create_string((const jerry_char_t*)ent.name); iotjs_jval_set_property_by_index(ret, idx, name); jerry_release_value(name); idx++; } iotjs_jargs_append_jval(&jarg, ret); jerry_release_value(ret); break; } case UV_FS_FSTAT: case UV_FS_STAT: { uv_stat_t s = (req->statbuf); jerry_value_t ret = MakeStatObject(&s); iotjs_jargs_append_jval(&jarg, ret); jerry_release_value(ret); break; } default: { iotjs_jargs_append_null(&jarg); break; } } } iotjs_make_callback(cb, jerry_create_undefined(), &jarg); iotjs_jargs_destroy(&jarg); iotjs_fs_reqwrap_destroy(req_wrap); }