kaa_error_t kaa_client_process_channel_disconnected(kaa_client_t *kaa_client) { KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM); kaa_error_t error_code = kaa_tcp_channel_check_keepalive(&kaa_client->channel); if (error_code) { KAA_LOG_ERROR(kaa_client->context->logger, error_code, "Failed to connect channel [0x%08X]", kaa_client->channel_id); } else { KAA_LOG_TRACE(kaa_client->context->logger, error_code, "Channel [0x%08X] successfully connected", kaa_client->channel_id); kaa_client->channel_state = KAA_CLIENT_CHANNEL_STATE_CONNECTED; } return error_code; }
void test_set_access_point(kaa_transport_channel_interface_t *channel) { ASSERT_NOT_NULL(channel); //Fill with fake pointers, just for non null kaa_transport_context_t transport_context; transport_context.kaa_context = (kaa_context_t*)calloc(1, sizeof(kaa_context_t)); transport_context.kaa_context->platform_protocol = (kaa_platform_protocol_t *)CONNECTION_DATA; transport_context.kaa_context->bootstrap_manager = (kaa_bootstrap_manager_t *)CONNECTION_DATA; kaa_error_t error_code = channel->init(channel->context, &transport_context); ASSERT_EQUAL(error_code, KAA_ERR_NONE); //Keepalive will be tested latter during CONNECT message creation error_code = kaa_tcp_channel_set_keepalive_timeout(channel, KEEPALIVE); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = kaa_tcp_channel_set_socket_events_callback(channel, kaa_tcp_channel_event_callback_fn, channel); //Use connection data to destination 192.168.77.2:9888 kaa_access_point_t access_point; access_point.id = 10; access_point.connection_data = CONNECTION_DATA; access_point.connection_data_len = sizeof(CONNECTION_DATA); reset_access_point_test_info(); error_code = channel->set_access_point(channel->context, &access_point); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code= kaa_tcp_channel_check_keepalive(channel); ASSERT_EQUAL(error_code, KAA_ERR_NONE); //Check correct call of gethostbyaddr ASSERT_EQUAL(access_point_test_info.gethostbyaddr_requested, true); //Check if new socket created ASSERT_EQUAL(access_point_test_info.new_socket_created, true); kaa_fd_t fd = -1; error_code = kaa_tcp_channel_get_descriptor(channel,&fd); ASSERT_EQUAL(error_code, KAA_ERR_NONE); //Check assigned fd ASSERT_EQUAL(fd, ACCESS_POINT_SOCKET_FD); access_point_test_info.fd = fd; //Check correct RD,WR operation, in this point we waiting for correct Connect to destination //So RD should be false, WR true CHECK_SOCKET_RW(channel,false,true); }
kaa_error_t kaa_client_process_channel_connected(kaa_client_t *kaa_client) { KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM); fd_set read_fds, write_fds, except_fds; struct timeval select_tv = { get_poll_timeout(kaa_client), 0 }; int channel_fd = 0; FD_ZERO(&read_fds); FD_ZERO(&write_fds); FD_ZERO(&except_fds); kaa_error_t error_code = kaa_tcp_channel_get_descriptor(&kaa_client->channel, &channel_fd); if(error_code) KAA_LOG_ERROR(kaa_client->context->logger, error_code, "No descriptor provided!"); if (kaa_tcp_channel_is_ready(&kaa_client->channel, FD_READ)) FD_SET(channel_fd, &read_fds); if (kaa_tcp_channel_is_ready(&kaa_client->channel, FD_WRITE)) FD_SET(channel_fd, &write_fds); int poll_result = select(channel_fd + 1, &read_fds, &write_fds, NULL, &select_tv); if (poll_result == 0) { error_code = kaa_tcp_channel_check_keepalive(&kaa_client->channel); } else if (poll_result > 0) { if (channel_fd >= 0) { if (FD_ISSET(channel_fd, &read_fds)) { KAA_LOG_DEBUG(kaa_client->context->logger, KAA_ERR_NONE, "Processing IN event for the client socket %d", channel_fd); error_code = kaa_tcp_channel_process_event(&kaa_client->channel, FD_READ); if (error_code) { KAA_LOG_ERROR(kaa_client->context->logger, error_code, "Failed to process IN event for the client socket %d", channel_fd); } } if (FD_ISSET(channel_fd, &write_fds)) { KAA_LOG_DEBUG(kaa_client->context->logger, KAA_ERR_NONE, "Processing OUT event for the client socket %d", channel_fd); error_code = kaa_tcp_channel_process_event(&kaa_client->channel, FD_WRITE); if (error_code) { KAA_LOG_ERROR(kaa_client->context->logger, error_code, "Failed to process OUT event for the client socket %d", channel_fd); } } } } else { KAA_LOG_ERROR(kaa_client->context->logger, KAA_ERR_BAD_STATE, "Failed to poll descriptors"); error_code = KAA_ERR_BAD_STATE; } if (kaa_client->channel_socket_closed) { KAA_LOG_INFO(kaa_client->context->logger, KAA_ERR_NONE, "Channel [0x%08X] connection terminated", kaa_client->channel_id); kaa_client->channel_state = KAA_CLIENT_CHANNEL_STATE_NOT_CONNECTED; if (error_code != KAA_ERR_EVENT_NOT_ATTACHED) { kaa_client_deinit_channel(kaa_client); } } return error_code; }
int kaa_demo_event_loop() { kaa_error_t error_code = kaa_start(kaa_context_); if (error_code) { KAA_LOG_FATAL(kaa_context_->logger, error_code,"Failed to start Kaa workflow"); return -1; } uint16_t select_timeout; error_code = kaa_tcp_channel_get_max_timeout(&operations_channel, &select_timeout); if (error_code) { KAA_LOG_FATAL(kaa_context_->logger, error_code,"Failed to get Operations channel keepalive timeout"); return -1; } if (select_timeout > KAA_DEMO_LOG_GENERATION_FREQUENCY) { select_timeout = KAA_DEMO_LOG_GENERATION_FREQUENCY; } fd_set read_fds, write_fds, except_fds; int ops_fd = 0, bootstrap_fd = 0; struct timeval select_tv = { 0, 0 }; int max_fd = 0; while (log_record_counter < KAA_DEMO_LOGS_TO_SEND) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); FD_ZERO(&except_fds); max_fd = 0; kaa_tcp_channel_get_descriptor(&operations_channel, &ops_fd); if (max_fd < ops_fd) max_fd = ops_fd; kaa_tcp_channel_get_descriptor(&bootstrap_channel, &bootstrap_fd); if (max_fd < bootstrap_fd) max_fd = bootstrap_fd; if (kaa_tcp_channel_is_ready(&operations_channel, FD_READ)) FD_SET(ops_fd, &read_fds); if (kaa_tcp_channel_is_ready(&operations_channel, FD_WRITE)) FD_SET(ops_fd, &write_fds); if (kaa_tcp_channel_is_ready(&bootstrap_channel, FD_READ)) FD_SET(bootstrap_fd, &read_fds); if (kaa_tcp_channel_is_ready(&bootstrap_channel, FD_WRITE)) FD_SET(bootstrap_fd, &write_fds); select_tv.tv_sec = select_timeout; select_tv.tv_usec = 0; int poll_result = select(max_fd + 1, &read_fds, &write_fds, NULL, &select_tv); if (poll_result == 0) { kaa_demo_add_log_record(); kaa_tcp_channel_check_keepalive(&operations_channel); kaa_tcp_channel_check_keepalive(&bootstrap_channel); } else if (poll_result > 0) { if (bootstrap_fd >= 0) { if (FD_ISSET(bootstrap_fd, &read_fds)) { KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing IN event for the Bootstrap client socket %d", bootstrap_fd); error_code = kaa_tcp_channel_process_event(&bootstrap_channel, FD_READ); if (error_code) KAA_LOG_ERROR(kaa_context_->logger, KAA_ERR_NONE,"Failed to process IN event for the Bootstrap client socket %d", bootstrap_fd); } if (FD_ISSET(bootstrap_fd, &write_fds)) { KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing OUT event for the Bootstrap client socket %d", bootstrap_fd); error_code = kaa_tcp_channel_process_event(&bootstrap_channel, FD_WRITE); if (error_code) KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process OUT event for the Bootstrap client socket %d", bootstrap_fd); } } if (ops_fd >= 0) { if (FD_ISSET(ops_fd, &read_fds)) { KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing IN event for the Operations client socket %d", ops_fd); error_code = kaa_tcp_channel_process_event(&operations_channel, FD_READ); if (error_code) KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process IN event for the Operations client socket %d", ops_fd); } if (FD_ISSET(ops_fd, &write_fds)) { KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing OUT event for the Operations client socket %d", ops_fd); error_code = kaa_tcp_channel_process_event(&operations_channel, FD_WRITE); if (error_code) KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process OUT event for the Operations client socket %d", ops_fd); } } } else { KAA_LOG_ERROR(kaa_context_->logger, KAA_ERR_BAD_STATE,"Failed to poll descriptors: %s", strerror(errno)); return -1; } } return 0; }
kaa_error_t kaa_client_process_channel_connected(kaa_client_t *kaa_client) { KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM); kaa_error_t error_code = KAA_ERR_NONE; esp8266_error_t esp_error = ESP8266_ERR_NONE; error_code = kaa_tcp_channel_check_keepalive(&kaa_client->channel); if (error_code) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Kaa tcp channel error check keepalive"); } int tmp = (get_sys_milis() / kaa_client->blink_timeout) % 2; if (kaa_client->blink_prev != (uint8)tmp) { kaa_client->blink_prev = (uint8)tmp; if (kaa_client->blink_prev) { ledOn(); if (kaa_client->boostrap_complete) { KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Process Bootstrap channel, state connected"); } else { KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Process Operation channel, state connected"); } } else ledOff(); } uint8 * buffer = NULL; size_t buffer_size = 0; error_code = kaa_tcp_channel_get_buffer_for_send(&kaa_client->channel, &buffer, &buffer_size); if (error_code) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Kaa tcp channel get buffer for send failed"); kaa_client_channel_error(kaa_client); } if (buffer_size > 0) { esp_error = esp8266_send_tcp(kaa_client->controler, kaa_client->channel_fd, buffer, buffer_size); if (esp_error) { if (esp_error != ESP8266_ERR_COMMAND_BUSY) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, KAA_ERR_NONE, "ESP8266 send tcp failed, code: %d", esp_error); kaa_client_channel_error(kaa_client); } } else { KAA_LOG_TRACE(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Channel(0x%08X) sending %lu bytes", kaa_client->channel_id, buffer_size); error_code = kaa_tcp_channel_free_send_buffer(&kaa_client->channel, buffer_size); if (error_code) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Kaa tcp channel error free buffer"); } } } if (kaa_tcp_channel_connection_is_ready_to_terminate(&kaa_client->channel)) { esp_error = esp8266_disconnect_tcp(kaa_client->controler, kaa_client->channel_fd); if (esp_error) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, KAA_ERR_NONE, "ESP8266 send tcp failed, code: %d", esp_error); } KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Channel(0x%08X) connection terminated", kaa_client->channel_id); error_code = kaa_client_channel_error(kaa_client); if (error_code) { KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Kaa tcp channel error"); } } return error_code; }
void thread_run_fn(uintptr_t arg) { if(!arg) { sndc_printf("Kaa client thread function Error, no args\n"); return; } kaa_client_t *self = (kaa_client_t *)arg; KAA_LOG_TRACE(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread started...."); sndc_sem_post(&self->logging_semophore); sndc_sock_fdset r_set; sndc_sock_fdset w_set; sndc_sock_fdset x_set; int r = 0; int max_fd = 0; uint32_t msec = 0; int ops_fd = -1, bootstrap_fd = -1; bool_t fdset = false; uint16_t timeout = self->max_update_time; kaa_error_t error_code; KAA_LOG_TRACE(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread(%s) wait starting...", self->thread_name); sndc_sem_wait(&self->start_semophore); KAA_LOG_INFO(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread(%s) started", self->thread_name); while(self->operate) { max_fd = 0; SNDC_FD_ZERO(&r_set); SNDC_FD_ZERO(&w_set); SNDC_FD_ZERO(&x_set); // This semaphore is used to synchronize main thread and kaa_client thread, // mostly for logging proposes. sndc_sem_tryWait(&self->logging_semophore); if (self->operations_channel.context) kaa_tcp_channel_get_descriptor(&self->operations_channel, &ops_fd); if(self->bootstrap_channel.context) kaa_tcp_channel_get_descriptor(&self->bootstrap_channel, &bootstrap_fd); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: descriptors: bootstrap(%d), operations(%d)", bootstrap_fd, ops_fd); print_mem_stat(self); if (bootstrap_fd >= 0) { fdset = false; if (kaa_tcp_channel_is_ready(&self->bootstrap_channel, FD_READ)) { SNDC_FD_SET(bootstrap_fd, &r_set); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Bootstrap READ set wait"); fdset = true; } if (kaa_tcp_channel_is_ready(&self->bootstrap_channel, FD_WRITE)) { SNDC_FD_SET(bootstrap_fd, &w_set); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Bootstrap WRITE set wait"); fdset = true; } if (fdset) { max_fd = MAX(max_fd, bootstrap_fd); SNDC_FD_SET(bootstrap_fd, &x_set); } } if (ops_fd >= 0) { fdset = false; if (kaa_tcp_channel_is_ready(&self->operations_channel, FD_READ)) { SNDC_FD_SET(ops_fd, &r_set); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Operations READ set wait"); fdset = true; } if (kaa_tcp_channel_is_ready(&self->operations_channel, FD_WRITE)) { SNDC_FD_SET(ops_fd, &w_set); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Operations WRITE set wait"); fdset = true; } if (fdset) { max_fd = MAX(max_fd, ops_fd); SNDC_FD_SET(ops_fd, &x_set); } } kaa_tcp_channel_get_max_timeout(&self->operations_channel, &timeout); self->timeval.tv_sec = timeout; if (timeout > self->max_update_time) self->timeval.tv_sec = self->max_update_time; self->timeval.tv_usec = 0; sndc_sem_post(&self->logging_semophore); r = sndc_sock_select(max_fd+1,&r_set,&w_set,&x_set,&self->timeval); sndc_sem_tryWait(&self->logging_semophore); if (r == 0) { msec = sndc_sys_getTimestamp_msec(); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: timeout (%d) expired", self->timeval.tv_sec); if (self->bootstrap_state == BOOTSRAP_FINISHED && bootstrap_fd == -1) { sndc_printf("Bootstrap channel deinit, Operations channel init %d\n", bootstrap_fd); KAA_LOG_INFO(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Bootstrap channel finish processing switching to Operations channel"); kaa_client_deinit_bootstrap_channel(self); kaa_client_init_operations_channel(self); } if (self->bootstrap_channel.context) { error_code = kaa_tcp_channel_check_keepalive(&self->bootstrap_channel); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Failed Keepalive Bootstrap(%d) check", bootstrap_fd); } } if (self->operations_channel.context) { error_code = kaa_tcp_channel_check_keepalive(&self->operations_channel); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Failed Keepalive Operations(%d) check", ops_fd); } } } else if (r > 0) { sndc_printf("FD SET return %d events\n", r); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: select() return %d events", r); if (bootstrap_fd >= 0) { fdset = false; if (SNDC_FD_ISSET(bootstrap_fd, &r_set)) { fdset = true; KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Read Event Bootstrap(%d)", bootstrap_fd); error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_READ); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Read Event Bootstrap(%d)", bootstrap_fd); } } if (fdset) r--; if (r > 0) { fdset = false; if (SNDC_FD_ISSET(bootstrap_fd, &w_set)) { fdset = true; KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Write Event Bootstrap(%d)", bootstrap_fd); error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_WRITE); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Write Event Bootstrap(%d)", bootstrap_fd); } } if (fdset) r--; } if (r > 0) { fdset = false; if (SNDC_FD_ISSET(bootstrap_fd, &x_set)) { fdset = true; sndc_printf("Exception Event Bootstrap %d\n", bootstrap_fd); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Exception Event Bootstrap(%d)", bootstrap_fd); error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_EXCEPTION); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Exception Event Bootstrap(%d)", bootstrap_fd); } } if (fdset) r--; } } if (r > 0 && ops_fd >= 0) { fdset = false; if (SNDC_FD_ISSET(ops_fd, &r_set)) { fdset = true; KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Read Event Operations(%d)", ops_fd); error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_READ); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Read Event Operations(%d)", ops_fd); } } if (fdset) r--; if (r > 0) { fdset = false; if (SNDC_FD_ISSET(ops_fd, &w_set)) { fdset = true; KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Write Event Operations(%d)", ops_fd); error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_WRITE); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Write Event Operations(%d)", ops_fd); } } } if (fdset) r--; if (r > 0) { fdset = false; if (SNDC_FD_ISSET(ops_fd, &x_set)) { fdset = true; sndc_printf("Exception Event Operations %d\n", ops_fd); KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Exception Event Operations(%d)", ops_fd); error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_EXCEPTION); if (error_code) { KAA_LOG_ERROR(self->kaa_context->logger, error_code, "IO LOOP: Failed Exception Event Operations(%d)", ops_fd); } } } } } else { KAA_LOG_ERROR(self->kaa_context->logger, KAA_ERR_BAD_STATE, "IO LOOP: Error %d returned from select()", r); } } KAA_LOG_INFO(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: Finished."); }