bool iotjs_i2c_open(iotjs_i2c_t* i2c) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c) iotjs_i2c_platform_data_t* platform_data = _this->platform_data; IOTJS_ASSERT(platform_data); // Init i2c context platform_data->i2c_context = iotbus_i2c_init(platform_data->bus); if (!platform_data->i2c_context) { DLOG("%s: cannot open I2C", __func__); return false; } // Set i2c frequency int ret = iotbus_i2c_set_frequency(platform_data->i2c_context, IOTBUS_I2C_STD); if (ret < 0) { DLOG("%s: cannot set frequency", __func__); return false; } if (iotbus_i2c_set_address(platform_data->i2c_context, _this->address) < 0) { DLOG("%s: cannot set address", __func__); return false; } return true; }
static void gpio_set_value_fd(iotjs_gpio_t* gpio, int fd) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); uv_mutex_lock(&_this->platform_data->mutex); _this->platform_data->value_fd = fd; uv_mutex_unlock(&_this->platform_data->mutex); }
// Recieved data to write from ClientRequest._write void iotjs_https_data_to_write(iotjs_https_t* https_data, iotjs_string_t read_chunk, const iotjs_jval_t* callback, const iotjs_jval_t* onwrite) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); if (_this->to_destroy_read_onwrite) { _this->to_destroy_read_onwrite = false; iotjs_string_destroy(&(_this->read_chunk)); iotjs_jval_destroy(&(_this->read_onwrite)); iotjs_jval_destroy(&(_this->read_callback)); } _this->read_chunk = read_chunk; _this->data_to_read = true; _this->read_callback = iotjs_jval_create_copied(callback); _this->read_onwrite = iotjs_jval_create_copied(onwrite); _this->to_destroy_read_onwrite = true; if (_this->request_done) { iotjs_https_call_read_onwrite_async(https_data); } else if (_this->is_stream_writable) { curl_easy_pause(_this->curl_easy_handle, CURLPAUSE_CONT); uv_timer_stop(&(_this->timeout)); uv_timer_start(&(_this->timeout), iotjs_https_uv_timeout_callback, 1, 0); } }
void iotjs_uart_open_worker(uv_work_t* work_req) { UART_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int fd = open(iotjs_string_data(&_this->device_path), O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { req_data->result = false; return; } struct termios options; tcgetattr(fd, &options); options.c_cflag = CLOCAL | CREAD; options.c_cflag |= baud_to_constant(_this->baud_rate); options.c_cflag |= databits_to_constant(_this->data_bits); options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &options); _this->device_fd = fd; uv_poll_t* poll_handle = &_this->poll_handle; uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); uv_poll_init(loop, poll_handle, fd); poll_handle->data = uart; uv_poll_start(poll_handle, UV_READABLE, iotjs_uart_read_cb); req_data->result = true; }
static bool gpio_set_edge(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char edge_path[GPIO_PATH_BUFFER_SIZE]; snprintf(edge_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_EDGE, _this->pin); iotjs_systemio_open_write_close(edge_path, gpio_edge_string[_this->edge]); if (_this->direction == kGpioDirectionIn && _this->edge != kGpioEdgeNone) { char value_path[GPIO_PATH_BUFFER_SIZE]; snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, _this->pin); if ((_this->platform_data->value_fd = open(value_path, O_RDONLY)) < 0) { DLOG("GPIO Error in open"); return false; } // Create edge detection thread // When the GPIO pin is closed, thread is terminated. int ret = uv_thread_create(&_this->platform_data->thread, gpio_edge_detection_cb, (void*)gpio); if (ret < 0) { DLOG("GPIO Error in uv_thread_create"); } return false; } return true; }
void iotjs_i2c_create_platform_data(iotjs_i2c_t* i2c) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->platform_data = IOTJS_ALLOC(iotjs_i2c_platform_data_t); _this->platform_data->i2c_context = NULL; }
bool iotjs_uart_write(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int bytesWritten = 0; unsigned offset = 0; int fd = _this->device_fd; const char* buf_data = iotjs_string_data(&_this->buf_data); DDDLOG("%s - data: %s", __func__, buf_data); do { errno = 0; bytesWritten = write(fd, buf_data + offset, _this->buf_len - offset); tcdrain(fd); DDDLOG("%s - size: %d", __func__, _this->buf_len - offset); if (bytesWritten != -1) { offset += bytesWritten; continue; } if (errno == EINTR) { continue; } return false; } while (_this->buf_len > offset); return true; }
// Set timeout for request. void iotjs_https_set_timeout(long ms, iotjs_https_t* https_data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); if (ms < 0) return; _this->timeout_ms = ms; uv_timer_start(&(_this->socket_timeout), iotjs_https_uv_socket_timeout_callback, 1, (uint64_t)ms); }
// This function is for signalling to curl a given time has passed. // This timeout is usually given by curl itself. void iotjs_https_uv_timeout_callback(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(timer); curl_multi_socket_action(_this->curl_multi_handle, CURL_SOCKET_TIMEOUT, 0, &_this->running_handles); iotjs_https_check_done(https_data); }
void iotjs_jargs_replace(iotjs_jargs_t* jargs, uint16_t index, const iotjs_jval_t* x) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jargs_t, jargs); IOTJS_ASSERT(index < _this->argc); iotjs_jval_destroy(&_this->argv[index]); _this->argv[index] = iotjs_jval_create_copied(x); }
jerry_value_t iotjs_i2c_set_platform_config(iotjs_i2c_t* i2c, const jerry_value_t jconfig) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); iotjs_i2c_platform_data_t* platform_data = _this->platform_data; DJS_GET_REQUIRED_CONF_VALUE(jconfig, platform_data->bus, IOTJS_MAGIC_STRING_BUS, number); return jerry_create_undefined(); }
static int gpio_get_value_fd(iotjs_gpio_t* gpio) { int fd; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); uv_mutex_lock(&_this->platform_data->mutex); fd = _this->platform_data->value_fd; uv_mutex_unlock(&_this->platform_data->mutex); return fd; }
//--------------LibTUV Callbacks------------------ // Callback called on closing handles during cleanup void iotjs_https_uv_close_callback(uv_handle_t* handle) { iotjs_https_t* https_data = (iotjs_https_t*)handle->data; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); _this->closing_handles = _this->closing_handles - 1; if (_this->closing_handles <= 0) { if (_this->poll_data != NULL) iotjs_https_poll_destroy(_this->poll_data); iotjs_jval_destroy(&_this->jthis_native); } }
void iotjs_https_poll_close(iotjs_https_poll_t* poll_data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_poll_t, poll_data); if (_this->closing == false) { _this->closing = true; uv_poll_stop(&_this->poll_handle); _this->poll_handle.data = _this->https_data; uv_close((uv_handle_t*)&_this->poll_handle, iotjs_https_uv_close_callback); } return; }
// Finish writing all data from ClientRequest Stream void iotjs_https_finish_request(iotjs_https_t* https_data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); _this->stream_ended = true; if (_this->request_done) { iotjs_https_cleanup(https_data); } else if (_this->is_stream_writable) { curl_easy_pause(_this->curl_easy_handle, CURLPAUSE_CONT); uv_timer_stop(&(_this->timeout)); uv_timer_start(&(_this->timeout), iotjs_https_uv_timeout_callback, 1, 0); } }
bool iotjs_gpio_close(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char buff[GPIO_PIN_BUFFER_SIZE]; snprintf(buff, GPIO_PIN_BUFFER_SIZE, "%d", _this->pin); gpio_set_value_fd(gpio, -1); close(_this->platform_data->value_fd); return iotjs_systemio_open_write_close(GPIO_PIN_FORMAT_UNEXPORT, buff); }
static void gpio_emit_change_event(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); jerry_value_t jgpio = _this->jobject; jerry_value_t jonChange = iotjs_jval_get_property(jgpio, "onChange"); IOTJS_ASSERT(jerry_value_is_function(jonChange)); iotjs_jhelper_call_ok(jonChange, jgpio, iotjs_jargs_get_empty()); jerry_release_value(jonChange); }
void iotjs_https_poll_append(iotjs_https_poll_t* head, iotjs_https_poll_t* poll_data) { iotjs_https_poll_t* current = head; iotjs_https_poll_t* next = iotjs_https_poll_get_next(current); while (next != NULL) { current = next; next = iotjs_https_poll_get_next(current); } IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_poll_t, current); _this->next = poll_data; }
void iotjs_spi_open_worker(uv_work_t* work_req) { SPI_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); if (!iotjs_spi_open(spi)) { DDLOG("%s - SPI open failed %d", __func__, _this->bus); req_data->result = false; return; } req_data->result = true; }
// ------------Functions almost directly called by JS---------- // Add a header to outgoing request void iotjs_https_add_header(iotjs_https_t* https_data, const char* char_header) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); _this->header_list = curl_slist_append(_this->header_list, char_header); if (_this->method == HTTPS_POST || _this->method == HTTPS_PUT) { if (strncmp(char_header, "Content-Length: ", strlen("Content-Length: ")) == 0) { const char* numberString = char_header + strlen("Content-Length: "); _this->content_length = strtol(numberString, NULL, 10); } } }
static void iotjs_spi_set_array_buffer(iotjs_spi_t* spi, const iotjs_jval_t* jtx_buf, const iotjs_jval_t* jrx_buf) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); int tx_buf_len = iotjs_spi_get_array_data(&_this->tx_buf_data, jtx_buf); int rx_buf_len = iotjs_spi_get_array_data(&_this->rx_buf_data, jrx_buf); IOTJS_ASSERT(_this->tx_buf_data != NULL && _this->rx_buf_data != NULL); IOTJS_ASSERT(tx_buf_len > 0 && rx_buf_len > 0 && tx_buf_len == rx_buf_len); _this->buf_len = tx_buf_len; }
size_t iotjs_bufferwrap_length(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); #ifndef NDEBUG iotjs_jval_t jbuf = iotjs_bufferwrap_jbuffer(bufferwrap); iotjs_jval_t jlength = iotjs_jval_get_property(&jbuf, IOTJS_MAGIC_STRING_LENGTH); size_t length = iotjs_jval_as_number(&jlength); IOTJS_ASSERT(length == _this->length); iotjs_jval_destroy(&jbuf); iotjs_jval_destroy(&jlength); #endif return _this->length; }
size_t iotjs_bufferwrap_copy_internal(iotjs_bufferwrap_t* bufferwrap, const char* src, size_t src_from, size_t src_to, size_t dst_from) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); size_t copied = 0; size_t dst_length = _this->length; for (size_t i = src_from, j = dst_from; i < src_to && j < dst_length; ++i, ++j) { *(_this->buffer + j) = *(src + i); ++copied; } return copied; }
bool iotjs_gpio_write(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char value_path[GPIO_PATH_BUFFER_SIZE]; snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, _this->pin); const char* buffer = _this->value ? "1" : "0"; DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, _this->value); return iotjs_systemio_open_write_close(value_path, buffer); }
bool iotjs_spi_close(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); if (_this->hSpi != NULL) { int err = iotbus_spi_close(_this->hSpi); if (err != 0) { DDLOG("%s - close failed: %d", __func__, err); return false; } _this->hSpi = NULL; } return true; }
void iotjs_jhandler_throw(iotjs_jhandler_t* jhandler, const iotjs_jval_t* err) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); #ifndef NDEBUG IOTJS_ASSERT(_this->finished == false); #endif iotjs_jval_destroy(&_this->jret); _this->jret = iotjs_jval_create_copied(err); jerry_value_set_error_flag(&_this->jret.unsafe.value); #ifndef NDEBUG _this->finished = true; #endif }
void iotjs_jhandler_return_jval(iotjs_jhandler_t* jhandler, const iotjs_jval_t* ret) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); #ifndef NDEBUG IOTJS_ASSERT(_this->finished == false); #endif iotjs_jval_destroy(&_this->jret); _this->jret = iotjs_jval_create_copied(ret); #ifndef NDEBUG _this->finished = true; #endif }
void WriteByteWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); IOTJS_ASSERT(!_this->i2c_master); int ret = i2c_write(_this->i2c_master, &_this->config, &req_data->byte, 1); if (ret < 0) { DDLOG("I2C WriteByteWorker : cannot write - %d", ret); req_data->error = kI2cErrWrite; return; } req_data->error = kI2cErrOk; }
// Start sending the request void iotjs_https_send_request(iotjs_https_t* https_data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_https_t, https_data); // Add all the headers to the easy handle curl_easy_setopt(_this->curl_easy_handle, CURLOPT_HTTPHEADER, _this->header_list); if (_this->method == HTTPS_POST && _this->content_length != -1) curl_easy_setopt(_this->curl_easy_handle, CURLOPT_POSTFIELDSIZE, _this->content_length); else if (_this->method == HTTPS_PUT && _this->content_length != -1) curl_easy_setopt(_this->curl_easy_handle, CURLOPT_INFILESIZE, _this->content_length); curl_multi_add_handle(_this->curl_multi_handle, _this->curl_easy_handle); }
void OpenWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->i2c_master = iotjs_i2c_config_nuttx(req_data->device); if (!_this->i2c_master) { DDLOG("I2C OpenWorker : cannot open"); req_data->error = kI2cErrOpen; return; } _this->config.frequency = I2C_DEFAULT_FREQUENCY; req_data->error = kI2cErrOk; }