static void transmit_command( BT_HDR *command, command_complete_cb complete_callback, command_status_cb status_callback, void *context) { uint8_t *stream; waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t)); if (!wait_entry) { LOG_ERROR("%s couldn't allocate space for wait entry.", __func__); return; } stream = command->data + command->offset; STREAM_TO_UINT16(wait_entry->opcode, stream); wait_entry->complete_callback = complete_callback; wait_entry->status_callback = status_callback; wait_entry->command = command; wait_entry->context = context; // 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; LOG_DEBUG("HCI Enqueue Comamnd opcode=0x%x\n", wait_entry->opcode); BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len); fixed_queue_enqueue(hci_host_env.command_queue, wait_entry); hci_host_task_post(); }
static void inbound_data_waiting(void *context) { eager_reader_t *reader = (eager_reader_t *)context; data_buffer_t *buffer = (data_buffer_t *)reader->allocator->alloc(reader->buffer_size + sizeof(data_buffer_t)); if (!buffer) { LOG_ERROR(LOG_TAG, "%s couldn't aquire memory for inbound data buffer.", __func__); return; } buffer->length = 0; buffer->offset = 0; int bytes_read = read(reader->inbound_fd, buffer->data, reader->buffer_size); if (bytes_read > 0) { // Save the data for later buffer->length = bytes_read; fixed_queue_enqueue(reader->buffers, buffer); // Tell consumers data is available by incrementing // the semaphore by the number of bytes we just read eventfd_write(reader->bytes_available_fd, bytes_read); } else { if (bytes_read == 0) LOG_WARN(LOG_TAG, "%s fd said bytes existed, but none were found.", __func__); else LOG_WARN(LOG_TAG, "%s unable to read from file descriptor: %s", __func__, strerror(errno)); reader->allocator->free(buffer); } }
int if_output(cbuf *b, ifnet *i) { bool release_sem = false; bool enqueue_failed = false; //printf("if out"); // stick the buffer on a transmit queue mutex_lock(&i->tx_queue_lock); if(fixed_queue_enqueue(&i->tx_queue, b) < 0) enqueue_failed = true; if(i->tx_queue.count == 1) release_sem = true; mutex_unlock(&i->tx_queue_lock); if(enqueue_failed) { cbuf_free_chain(b); return ERR_NO_MEMORY; } if(release_sem) sem_release(i->tx_queue_sem); //printf("if %x out ok\n", i); return NO_ERROR; }
/******************************************************************************* ** ** Function btc_a2dp_sink_enque_buf ** ** Description This function is called by the av_co to fill A2DP Sink Queue ** ** ** Returns size of the queue *******************************************************************************/ UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt) { tBT_SBC_HDR *p_msg; if (btc_aa_snk_cb.rx_flush == TRUE) { /* Flush enabled, do not enque*/ return fixed_queue_length(btc_aa_snk_cb.RxSbcQ); } if (fixed_queue_length(btc_aa_snk_cb.RxSbcQ) >= MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ) { APPL_TRACE_WARNING("Pkt dropped\n"); return fixed_queue_length(btc_aa_snk_cb.RxSbcQ); } APPL_TRACE_DEBUG("btc_a2dp_sink_enque_buf + "); /* allocate and Queue this buffer */ if ((p_msg = (tBT_SBC_HDR *) osi_malloc(sizeof(tBT_SBC_HDR) + p_pkt->offset + p_pkt->len)) != NULL) { memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len)); p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f; APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed); fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg); btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT); } else { /* let caller deal with a failed allocation */ APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - "); } return fixed_queue_length(btc_aa_snk_cb.RxSbcQ); }
void btu_oneshot_alarm_cb(void *data) { assert(data != NULL); TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; btu_stop_timer_oneshot(p_tle); fixed_queue_enqueue(btu_oneshot_alarm_queue, p_tle); }
static void transmit_downward(data_dispatcher_type_t type, void *data) { if (type == MSG_STACK_TO_HC_HCI_CMD) { // TODO(zachoverflow): eliminate this call transmit_command((BT_HDR *)data, NULL, NULL, NULL); LOG_WARN(LOG_TAG, "%s legacy transmit of command. Use transmit_command instead.", __func__); } else { fixed_queue_enqueue(packet_queue, data); } }
static void transmit_downward(uint16_t type, void *data) { if (type == MSG_STACK_TO_HC_HCI_CMD) { transmit_command((BT_HDR *)data, NULL, NULL, NULL); LOG_WARN("%s legacy transmit of command. Use transmit_command instead.\n", __func__); } else { fixed_queue_enqueue(hci_host_env.packet_queue, data); } //ke_event_set(KE_EVENT_HCI_HOST_THREAD); hci_host_task_post(); }
static void transmit_downward(uint16_t type, void *data) { if (type == MSG_STACK_TO_HC_HCI_CMD) { transmit_command((BT_HDR *)data, NULL, NULL, NULL); HCI_TRACE_WARNING("%s legacy transmit of command. Use transmit_command instead.\n", __func__); } else { fixed_queue_enqueue(hci_host_env.packet_queue, data); } hci_host_task_post(TASK_POST_BLOCKING); }
// Callback for the fragmenter to dispatch up a completely reassembled packet static void dispatch_reassembled(BT_HDR *packet) { // Events should already have been dispatched before this point assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT); assert(upwards_data_queue != NULL); if (upwards_data_queue) { fixed_queue_enqueue(upwards_data_queue, packet); } else { LOG_ERROR(LOG_TAG, "%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__); buffer_allocator->free(packet); } }
// Callback for the fragmenter to dispatch up a completely reassembled packet static void dispatch_reassembled(BT_HDR *packet) { // Events should already have been dispatched before this point if (hci_host_env.upwards_data_queue) { fixed_queue_enqueue(hci_host_env.upwards_data_queue, packet); btu_task_post(SIG_BTU_WORK); //Tell Up-layer received packet. } else { LOG_DEBUG("%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__); buffer_allocator->free(packet); } }
bool data_dispatcher_dispatch(data_dispatcher_t *dispatcher, data_dispatcher_type_t type, void *data) { assert(dispatcher != NULL); assert(data != NULL); fixed_queue_t *queue = hash_map_get(dispatcher->dispatch_table, (void *)type); if (!queue) queue = dispatcher->default_queue; if (queue) fixed_queue_enqueue(queue, data); else LOG_WARN(LOG_TAG, "%s has no handler for type (%zd) in data dispatcher named: %s", __func__, type, dispatcher->name); return queue != NULL; }
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; }
bool thread_post(thread_t *thread, thread_fn func, void *context) { assert(thread != NULL); assert(func != NULL); // TODO(sharvil): if the current thread == |thread| and we've run out // of queue space, we should abort this operation, otherwise we'll // deadlock. // Queue item is freed either when the queue itself is destroyed // or when the item is removed from the queue for dispatch. work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t)); if (!item) { LOG_ERROR("%s unable to allocate memory: %s", __func__, strerror(errno)); return false; } item->func = func; item->context = context; fixed_queue_enqueue(thread->work_queue, item); return true; }
static void transmit_command( BT_HDR *command, command_complete_cb complete_callback, command_status_cb status_callback, void *context) { waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t)); if (!wait_entry) { LOG_ERROR(LOG_TAG, "%s couldn't allocate space for wait entry.", __func__); return; } uint8_t *stream = command->data + command->offset; STREAM_TO_UINT16(wait_entry->opcode, stream); wait_entry->complete_callback = complete_callback; wait_entry->status_callback = status_callback; wait_entry->command = command; wait_entry->context = context; // 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); }
/******************************************************************************* ** ** Function rfc_check_send_cmd ** ** Description This function is called to send an RFCOMM command message ** or to handle the RFCOMM command message queue. ** ** Returns void ** *******************************************************************************/ void rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf) { BT_HDR *p; /* if passed a buffer queue it */ if (p_buf != NULL) { if (p_mcb->cmd_q == NULL) { RFCOMM_TRACE_ERROR("%s: empty queue: p_mcb = %p p_mcb->lcid = %u cached p_mcb = %p", __func__, p_mcb, p_mcb->lcid, rfc_find_lcid_mcb(p_mcb->lcid)); } fixed_queue_enqueue(p_mcb->cmd_q, p_buf); } /* handle queue if L2CAP not congested */ while (p_mcb->l2cap_congested == FALSE) { if ((p = (BT_HDR *)fixed_queue_try_dequeue(p_mcb->cmd_q)) == NULL) { break; } L2CA_DataWrite (p_mcb->lcid, p); } }
static void btu_l2cap_alarm_cb(void *data) { assert(data != NULL); TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; fixed_queue_enqueue(btu_l2cap_alarm_queue, p_tle); }
/******************************************************************************* ** ** Function l2c_ucd_enqueue_pending_out_sec_q ** ** Description enqueue outgoing UCD packet into security pending queue ** and check congestion ** ** Return None ** *******************************************************************************/ void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB *p_ccb, void *p_data) { fixed_queue_enqueue(p_ccb->p_lcb->ucd_out_sec_pending_q, p_data); l2cu_check_channel_congestion (p_ccb); }
/******************************************************************************* ** ** Function PORT_DataInd ** ** Description This function is called from the RFCOMM layer when data ** buffer is received from the peer. ** *******************************************************************************/ void PORT_DataInd (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); UINT8 rx_char1; UINT32 events = 0; UINT8 *p; int i; RFCOMM_TRACE_EVENT("PORT_DataInd with data length %d, p_mcb:%p,p_port:%p,dlci:%d", p_buf->len, p_mcb, p_port, dlci); if (!p_port) { osi_free (p_buf); return; } /* If client registered callout callback with flow control we can just deliver receive data */ if (p_port->p_data_co_callback) { /* Another packet is delivered to user. Send credits to peer if required */ if (p_port->p_data_co_callback(p_port->inx, (UINT8 *)p_buf, -1, DATA_CO_CALLBACK_TYPE_INCOMING)) { port_flow_control_peer(p_port, TRUE, 1); } else { port_flow_control_peer(p_port, FALSE, 0); } //osi_free (p_buf); return; } else { RFCOMM_TRACE_DEBUG("PORT_DataInd, p_port:%p, p_data_co_callback is null", p_port); } /* If client registered callback we can just deliver receive data */ if (p_port->p_data_callback) { /* Another packet is delivered to user. Send credits to peer if required */ port_flow_control_peer(p_port, TRUE, 1); p_port->p_data_callback (p_port->inx, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len); osi_free (p_buf); return; } /* Check if rx queue exceeds the limit */ if ((p_port->rx.queue_size + p_buf->len > PORT_RX_CRITICAL_WM) || (fixed_queue_length(p_port->rx.queue) + 1 > p_port->rx_buf_critical)) { RFCOMM_TRACE_EVENT ("PORT_DataInd. Buffer over run. Dropping the buffer"); osi_free (p_buf); RFCOMM_LineStatusReq (p_mcb, dlci, LINE_STATUS_OVERRUN); return; } /* If user registered to receive notification when a particular byte is */ /* received we mast check all received bytes */ if (((rx_char1 = p_port->user_port_pars.rx_char1) != 0) && (p_port->ev_mask & PORT_EV_RXFLAG)) { for (i = 0, p = (UINT8 *)(p_buf + 1) + p_buf->offset; i < p_buf->len; i++) { if (*p++ == rx_char1) { events |= PORT_EV_RXFLAG; break; } } } osi_mutex_global_lock(); fixed_queue_enqueue(p_port->rx.queue, p_buf); p_port->rx.queue_size += p_buf->len; osi_mutex_global_unlock(); /* perform flow control procedures if necessary */ port_flow_control_peer(p_port, FALSE, 0); /* If user indicated flow control can not deliver any notifications to him */ if (p_port->rx.user_fc) { if (events & PORT_EV_RXFLAG) { p_port->rx_flag_ev_pending = TRUE; } return; } events |= PORT_EV_RXCHAR; /* Mask out all events that are not of interest to user */ events &= p_port->ev_mask; if (p_port->p_callback && events) { p_port->p_callback (events, p_port->inx); } }