future_t * future_collection_insert_bulk ( mongoc_collection_ptr collection, mongoc_insert_flags_t flags, const_bson_ptr_ptr documents, uint32_t n_documents, const_mongoc_write_concern_ptr write_concern, bson_error_ptr error) { future_t *future = future_new (future_value_bool_type, 6); future_value_set_mongoc_collection_ptr ( future_get_param (future, 0), collection); future_value_set_mongoc_insert_flags_t ( future_get_param (future, 1), flags); future_value_set_const_bson_ptr_ptr ( future_get_param (future, 2), documents); future_value_set_uint32_t ( future_get_param (future, 3), n_documents); future_value_set_const_mongoc_write_concern_ptr ( future_get_param (future, 4), write_concern); future_value_set_bson_error_ptr ( future_get_param (future, 5), error); future_start (future, background_mongoc_collection_insert_bulk); return future; }
future_t * future_client_get_gridfs ( mongoc_client_ptr client, const_char_ptr db, const_char_ptr prefix, bson_error_ptr error) { future_t *future = future_new (future_value_mongoc_gridfs_ptr_type, 4); future_value_set_mongoc_client_ptr ( future_get_param (future, 0), client); future_value_set_const_char_ptr ( future_get_param (future, 1), db); future_value_set_const_char_ptr ( future_get_param (future, 2), prefix); future_value_set_bson_error_ptr ( future_get_param (future, 3), error); future_start (future, background_mongoc_client_get_gridfs); return future; }
future_t * future_topology_select ( mongoc_topology_ptr topology, mongoc_ss_optype_t optype, const_mongoc_read_prefs_ptr read_prefs, int64_t local_threshold_ms, bson_error_ptr error) { future_t *future = future_new (future_value_mongoc_server_description_ptr_type, 5); future_value_set_mongoc_topology_ptr ( future_get_param (future, 0), topology); future_value_set_mongoc_ss_optype_t ( future_get_param (future, 1), optype); future_value_set_const_mongoc_read_prefs_ptr ( future_get_param (future, 2), read_prefs); future_value_set_int64_t ( future_get_param (future, 3), local_threshold_ms); future_value_set_bson_error_ptr ( future_get_param (future, 4), error); future_start (future, background_mongoc_topology_select); return future; }
future_t * future_collection_aggregate ( mongoc_collection_ptr collection, mongoc_query_flags_t flags, const_bson_ptr pipeline, const_bson_ptr options, const_mongoc_read_prefs_ptr read_prefs) { future_t *future = future_new (future_value_mongoc_cursor_ptr_type, 5); future_value_set_mongoc_collection_ptr ( future_get_param (future, 0), collection); future_value_set_mongoc_query_flags_t ( future_get_param (future, 1), flags); future_value_set_const_bson_ptr ( future_get_param (future, 2), pipeline); future_value_set_const_bson_ptr ( future_get_param (future, 3), options); future_value_set_const_mongoc_read_prefs_ptr ( future_get_param (future, 4), read_prefs); future_start (future, background_mongoc_collection_aggregate); return future; }
future_t * future_gridfs_file_writev ( mongoc_gridfs_file_t_ptr file, mongoc_iovec_t_ptr iov, size_t iovcnt, uint32_t timeout_msec) { future_t *future = future_new (future_value_ssize_t_type, 4); future_value_set_mongoc_gridfs_file_t_ptr ( future_get_param (future, 0), file); future_value_set_mongoc_iovec_t_ptr ( future_get_param (future, 1), iov); future_value_set_size_t ( future_get_param (future, 2), iovcnt); future_value_set_uint32_t ( future_get_param (future, 3), timeout_msec); future_start (future, background_mongoc_gridfs_file_writev); return future; }
future_t * future_client_command_simple ( mongoc_client_ptr client, const_char_ptr db_name, const_bson_ptr command, const_mongoc_read_prefs_ptr read_prefs, bson_ptr reply, bson_error_ptr error) { future_t *future = future_new (future_value_bool_type, 6); future_value_set_mongoc_client_ptr ( future_get_param (future, 0), client); future_value_set_const_char_ptr ( future_get_param (future, 1), db_name); future_value_set_const_bson_ptr ( future_get_param (future, 2), command); future_value_set_const_mongoc_read_prefs_ptr ( future_get_param (future, 3), read_prefs); future_value_set_bson_ptr ( future_get_param (future, 4), reply); future_value_set_bson_error_ptr ( future_get_param (future, 5), error); future_start (future, background_mongoc_client_command_simple); return future; }
promise_t * promise_new (void) { promise_t *self = (promise_t *) malloc (sizeof (promise_t)); assert (self); self->future = future_new (); return self; }
future_t * future_cursor_destroy ( mongoc_cursor_ptr cursor) { future_t *future = future_new (future_value_void_type, 1); future_value_set_mongoc_cursor_ptr ( future_get_param (future, 0), cursor); future_start (future, background_mongoc_cursor_destroy); return future; }
future_t * future_collection_find_and_modify ( mongoc_collection_ptr collection, const_bson_ptr query, const_bson_ptr sort, const_bson_ptr update, const_bson_ptr fields, bool _remove, bool upsert, bool _new, bson_ptr reply, bson_error_ptr error) { future_t *future = future_new (future_value_bool_type, 10); future_value_set_mongoc_collection_ptr ( future_get_param (future, 0), collection); future_value_set_const_bson_ptr ( future_get_param (future, 1), query); future_value_set_const_bson_ptr ( future_get_param (future, 2), sort); future_value_set_const_bson_ptr ( future_get_param (future, 3), update); future_value_set_const_bson_ptr ( future_get_param (future, 4), fields); future_value_set_bool ( future_get_param (future, 5), _remove); future_value_set_bool ( future_get_param (future, 6), upsert); future_value_set_bool ( future_get_param (future, 7), _new); future_value_set_bson_ptr ( future_get_param (future, 8), reply); future_value_set_bson_error_ptr ( future_get_param (future, 9), error); future_start (future, background_mongoc_collection_find_and_modify); return future; }
future_t * future_database_get_collection_names ( mongoc_database_ptr database, bson_error_ptr error) { future_t *future = future_new (future_value_char_ptr_ptr_type, 2); future_value_set_mongoc_database_ptr ( future_get_param (future, 0), database); future_value_set_bson_error_ptr ( future_get_param (future, 1), error); future_start (future, background_mongoc_database_get_collection_names); return future; }
future_t * future_client_get_database_names ( mongoc_client_ptr client, bson_error_ptr error) { future_t *future = future_new (future_value_char_ptr_ptr_type, 2); future_value_set_mongoc_client_ptr ( future_get_param (future, 0), client); future_value_set_bson_error_ptr ( future_get_param (future, 1), error); future_start (future, background_mongoc_client_get_database_names); return future; }
future_t * future_cursor_next ( mongoc_cursor_ptr cursor, const_bson_ptr_ptr doc) { future_t *future = future_new (future_value_bool_type, 2); future_value_set_mongoc_cursor_ptr ( future_get_param (future, 0), cursor); future_value_set_const_bson_ptr_ptr ( future_get_param (future, 1), doc); future_start (future, background_mongoc_cursor_next); return future; }
future_t * future_client_kill_cursor ( mongoc_client_ptr client, int64_t cursor_id) { future_t *future = future_new (future_value_void_type, 2); future_value_set_mongoc_client_ptr ( future_get_param (future, 0), client); future_value_set_int64_t ( future_get_param (future, 1), cursor_id); future_start (future, background_mongoc_client_kill_cursor); return future; }
static future_t *transmit_command_futured(BT_HDR *command) { waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t)); assert(wait_entry != NULL); future_t *future = future_new(); uint8_t *stream = command->data + command->offset; STREAM_TO_UINT16(wait_entry->opcode, stream); wait_entry->complete_future = future; wait_entry->command = command; // Store the command message type in the event field // in case the upper layer didn't already command->event = MSG_STACK_TO_HC_HCI_CMD; fixed_queue_enqueue(command_queue, wait_entry); return future; }
future_t * future_gridfs_file_seek ( mongoc_gridfs_file_t_ptr file, int64_t delta, int whence) { future_t *future = future_new (future_value_int_type, 3); future_value_set_mongoc_gridfs_file_t_ptr ( future_get_param (future, 0), file); future_value_set_int64_t ( future_get_param (future, 1), delta); future_value_set_int ( future_get_param (future, 2), whence); future_start (future, background_mongoc_gridfs_file_seek); return future; }
future_t * future_bulk_operation_execute ( mongoc_bulk_operation_ptr bulk, bson_ptr reply, bson_error_ptr error) { future_t *future = future_new (future_value_uint32_t_type, 3); future_value_set_mongoc_bulk_operation_ptr ( future_get_param (future, 0), bulk); future_value_set_bson_ptr ( future_get_param (future, 1), reply); future_value_set_bson_error_ptr ( future_get_param (future, 2), error); future_start (future, background_mongoc_bulk_operation_execute); return future; }
static future_t *start_up(void) { LOG_INFO(LOG_TAG, "%s", __func__); // The host is only allowed to send at most one command initially, // as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control) // This value can change when you get a command complete or command status event. command_credits = 1; firmware_is_configured = false; pthread_mutex_init(&commands_pending_response_lock, NULL); // TODO(armansito): cutils/properties.h is only being used to pull-in runtime // settings on Android. Remove this conditional include once we have a generic // way to obtain system properties. For now, always use the default timeout on // non-Android builds. period_ms_t startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS; #if !defined(OS_GENERIC) // Grab the override startup timeout ms, if present. char timeout_prop[PROPERTY_VALUE_MAX]; if (!property_get("bluetooth.enable_timeout_ms", timeout_prop, STRING_VALUE_OF(DEFAULT_STARTUP_TIMEOUT_MS)) || (startup_timeout_ms = atoi(timeout_prop)) < 100) startup_timeout_ms = DEFAULT_STARTUP_TIMEOUT_MS; #endif // !defined(OS_GENERIC) startup_timer = non_repeating_timer_new(startup_timeout_ms, startup_timer_expired, NULL); if (!startup_timer) { LOG_ERROR(LOG_TAG, "%s unable to create startup timer.", __func__); goto error; } // Make sure we run in a bounded amount of time non_repeating_timer_restart(startup_timer); epilog_timer = non_repeating_timer_new(EPILOG_TIMEOUT_MS, epilog_timer_expired, NULL); if (!epilog_timer) { LOG_ERROR(LOG_TAG, "%s unable to create epilog timer.", __func__); goto error; } command_response_timer = non_repeating_timer_new(COMMAND_PENDING_TIMEOUT, command_timed_out, NULL); if (!command_response_timer) { LOG_ERROR(LOG_TAG, "%s unable to create command response timer.", __func__); goto error; } command_queue = fixed_queue_new(SIZE_MAX); if (!command_queue) { LOG_ERROR(LOG_TAG, "%s unable to create pending command queue.", __func__); goto error; } packet_queue = fixed_queue_new(SIZE_MAX); if (!packet_queue) { LOG_ERROR(LOG_TAG, "%s unable to create pending packet queue.", __func__); goto error; } thread = thread_new("hci_thread"); if (!thread) { LOG_ERROR(LOG_TAG, "%s unable to create thread.", __func__); goto error; } commands_pending_response = list_new(NULL); if (!commands_pending_response) { LOG_ERROR(LOG_TAG, "%s unable to create list for commands pending response.", __func__); goto error; } memset(incoming_packets, 0, sizeof(incoming_packets)); packet_fragmenter->init(&packet_fragmenter_callbacks); fixed_queue_register_dequeue(command_queue, thread_get_reactor(thread), event_command_ready, NULL); fixed_queue_register_dequeue(packet_queue, thread_get_reactor(thread), event_packet_ready, NULL); vendor->open(btif_local_bd_addr.address, &interface); hal->init(&hal_callbacks, thread); low_power_manager->init(thread); vendor->set_callback(VENDOR_CONFIGURE_FIRMWARE, firmware_config_callback); vendor->set_callback(VENDOR_CONFIGURE_SCO, sco_config_callback); vendor->set_callback(VENDOR_DO_EPILOG, epilog_finished_callback); if (!hci_inject->open(&interface)) { // TODO(sharvil): gracefully propagate failures from this layer. } int power_state = BT_VND_PWR_OFF; #if (defined (BT_CLEAN_TURN_ON_DISABLED) && BT_CLEAN_TURN_ON_DISABLED == TRUE) LOG_WARN(LOG_TAG, "%s not turning off the chip before turning on.", __func__); // So apparently this hack was needed in the past because a Wingray kernel driver // didn't handle power off commands in a powered off state correctly. // The comment in the old code said the workaround should be removed when the // problem was fixed. Sadly, I have no idea if said bug was fixed or if said // kernel is still in use, so we must leave this here for posterity. #sadpanda #else // cycle power on the chip to ensure it has been reset vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state); #endif power_state = BT_VND_PWR_ON; vendor->send_command(VENDOR_CHIP_POWER_CONTROL, &power_state); startup_future = future_new(); LOG_DEBUG(LOG_TAG, "%s starting async portion", __func__); thread_post(thread, event_finish_startup, NULL); return startup_future; error:; shut_down(); // returns NULL so no need to wait for it return future_new_immediate(FUTURE_FAIL); }