Beispiel #1
0
void processUsbSendQueue(UsbDevice* usbDevice) {
    while(usbDevice->configured &&
            !QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) {
        // Make sure the USB write is 100% complete before messing with this buffer
        // after we copy the message into it - the Microchip library doesn't copy
        // the data to its own internal buffer. See #171 for background on this
        // issue.
        if(!waitForHandle(usbDevice)) {
            return;
        }

        int byteCount = 0;
        while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue) && byteCount < 64) {
            usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue);
        }

        int nextByteIndex = 0;
        while(nextByteIndex < byteCount) {
            if(!waitForHandle(usbDevice)) {
                return;
            }
            int bytesToTransfer = min(USB_PACKET_SIZE, byteCount - nextByteIndex);
            usbDevice->deviceToHostHandle = usbDevice->device.GenWrite(
                    usbDevice->inEndpoint, &usbDevice->sendBuffer[nextByteIndex], bytesToTransfer);
            nextByteIndex += bytesToTransfer;
        }
    }
}
Beispiel #2
0
int32_t session_end( struct session * self, sid_t id )
{
    // 由于会话已经从管理器中删除了
    // 会话中的ID已经非法

    // 清空发送队列
    uint32_t count = session_sendqueue_count(self);
    if ( count > 0 )
    {
        syslog(LOG_WARNING,
                "%s(SID=%ld)'s Out-Message-List (%d) is not empty .", __FUNCTION__, id, count );

        for ( ; count > 0; --count )
        {
            struct message * msg = NULL;
            QUEUE_POP(sendqueue)( &self->sendqueue, &msg );

            // 检查消息是否可以销毁了
            message_add_failure( msg, id );
            if ( message_is_complete(msg) )
            {
                message_destroy( msg );
            }
        }
    }

    // 停止会话
    _stop( self );
    _del_session( self );

    return 0;
}
Beispiel #3
0
/* clean connection */
void conn_clean(CONN **pconn)
{
    CHUNK *cp = NULL;

    if(*pconn)
    {
        if((*pconn)->timer) {TIMER_CLEAN((*pconn)->timer);}
        if((*pconn)->event) (*pconn)->event->clean(&((*pconn)->event));
        /* Clean BUFFER */
        MB_CLEAN((*pconn)->buffer);
        /* Clean OOB */
        MB_CLEAN((*pconn)->oob);
        /* Clean cache */
        MB_CLEAN((*pconn)->cache);
        /* Clean packet */
        MB_CLEAN((*pconn)->packet);
        /* Clean chunk */
        CK_CLEAN((*pconn)->chunk);
        /* Clean send queue */
        if((*pconn)->send_queue)
        {
            while(QUEUE_POP((*pconn)->send_queue, PCHUNK, &cp) == 0){CK_CLEAN(cp);}
            QUEUE_CLEAN((*pconn)->send_queue);
        }
        free(*pconn);
        (*pconn) = NULL;
    }
}
Beispiel #4
0
uint32_t _process( struct iothreads * parent, struct iothread * thread, struct taskqueue * doqueue )
{
    uint32_t nprocess = 0;

    // 交换任务队列
    msgqueue_swap( thread->queue, doqueue );

    // 获取最大任务数
    nprocess = QUEUE_COUNT(taskqueue)(doqueue);

    // 处理任务
    for( ; QUEUE_COUNT(taskqueue)(doqueue) > 0; )
    {
        struct task task;
        QUEUE_POP(taskqueue)( doqueue, &task );

        // 网络任务处理
        if ( task.type == eTaskType_User )
        {
            parent->processor( parent->context,
                    thread->index, task.utype, task.taskdata );
        }
        else if ( task.type == eTaskType_Data )
        {
            parent->processor( parent->context,
                    thread->index, task.utype, (void *)(task.data) );
        }
    }

    return nprocess;
}
/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the serial monitor.
 */
void receiveCan(CanBus* bus) {
    // TODO what happens if we process until the queue is empty?
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        decodeCanMessage(bus, message.id, message.data);
        bus->lastMessageReceived = systemTimeMs();
    }
}
END_TEST

START_TEST (test_send_using_default)
{
    fail_unless(sendCanSignal(&SIGNALS[0], cJSON_CreateNumber(0xa), SIGNALS,
                SIGNAL_COUNT));
    CanMessage queuedMessage = QUEUE_POP(CanMessage, &SIGNALS[0].message->bus->sendQueue);
    ck_assert_int_eq(queuedMessage.data, 0x1e);
}
END_TEST

START_TEST (test_send_with_custom_with_states)
{
    fail_unless(sendCanSignal(&SIGNALS[1],
                cJSON_CreateString(SIGNAL_STATES[0][1].name), SIGNALS,
                SIGNAL_COUNT));
    CanMessage queuedMessage = QUEUE_POP(CanMessage, &SIGNALS[1].message->bus->sendQueue);
    ck_assert_int_eq(queuedMessage.data, 0x20);
}
END_TEST

START_TEST (test_swaps_byte_order)
{
    CanMessage message = {&bus, 42};
    enqueueCanMessage(&message, 0x123456);

    CanMessage queuedMessage = QUEUE_POP(CanMessage, &message.bus->sendQueue);
    ck_assert_int_eq(queuedMessage.data, 0x5634120000000000LLU);
}
Beispiel #9
0
int32_t msgqueue_pop( struct msgqueue * self, struct task * task )
{
    int32_t rc = -1;

    pthread_mutex_lock( &self->lock );
    rc = QUEUE_POP(taskqueue)(&self->queue, task);
    pthread_mutex_unlock( &self->lock );

    return rc;
}
Beispiel #10
0
// The chipKIT version of this function is blocking. It will entirely flush the
// send queue before returning.
void processSerialSendQueue(SerialDevice* device) {
    int byteCount = 0;
    char sendBuffer[MAX_MESSAGE_SIZE];
    while(!QUEUE_EMPTY(uint8_t, &device->sendQueue) &&
                    byteCount < MAX_MESSAGE_SIZE) {
        sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &device->sendQueue);
    }

    if(byteCount > 0) {
        ((HardwareSerial*)device->controller)->write((const uint8_t*)sendBuffer,
                byteCount);
    }
}
Beispiel #11
0
/* write handler */
int conn_write_handler(CONN *conn)
{
    int ret = -1, n = 0;
    CONN_CHECK_RET(conn, ret);
    CHUNK *cp = NULL;

    if(conn && conn->send_queue && QTOTAL(conn->send_queue) > 0)
    {
        DEBUG_LOGGER(conn->logger, "Ready for send data to %s:%d via %d "
                "qtotal:%d qhead:%d qcount:%d",
                conn->ip, conn->port, conn->fd, QTOTAL(conn->send_queue),
                QHEAD(conn->send_queue), QCOUNT(conn->send_queue));   
        if(QUEUE_HEAD(conn->send_queue, PCHUNK, &cp) == 0)
        {
            DEBUG_LOGGER(conn->logger, "Ready for send data to %s:%d via %d qtotal:%d pcp:%08x",
                    conn->ip, conn->port, conn->fd, QTOTAL(conn->send_queue), cp);   
            if((n = CHUNK_WRITE(cp, conn->fd)) > 0)
            {
                conn->sent_data_total += n;
                DEBUG_LOGGER(conn->logger, "Sent %d byte(s) (total sent %lld) "
                        "to %s:%d via %d leave %lld", n, conn->sent_data_total, 
                        conn->ip, conn->port, conn->fd, CK_LEFT(cp));
                /* CONN TIMER sample */
                TIMER_SAMPLE(conn->timer);
                if(CHUNK_STATUS(cp) == CHUNK_STATUS_OVER )
                {
                    if(QUEUE_POP(conn->send_queue, PCHUNK, &cp) == 0)
                    {
                        DEBUG_LOGGER(conn->logger, "Completed chunk[%08x] and clean it leave %d",
                                cp, QTOTAL(conn->send_queue));
                        CK_CLEAN(cp);
                    }
                }
                ret = 0;
            }
            else
            {
                FATAL_LOGGER(conn->logger, "Sending data to %s:%d via %d failed, %s",
                        conn->ip, conn->port, conn->fd, strerror(errno));
                /* Terminate connection */
                CONN_TERMINATE(conn);
            }
        }
        if(QTOTAL(conn->send_queue) <= 0)
        {
            conn->event->del(conn->event, E_WRITE);
        }
    }
    return ret;
}
Beispiel #12
0
void processUsbSendQueue(UsbDevice* usbDevice) {
    if(usbDevice->configured && vbusEnabled()) {
        // if there's nothing attached to the analog input it floats at ~828, so
        // if we're powering the board from micro-USB (and the jumper is going
        // to 5v and not the analog input), this is still OK.
        debug("USB no longer detected - marking unconfigured");
        usbDevice->configured = false;
    }

    // Don't touch usbDevice->sendBuffer if there's still a pending transfer
    if(!waitForHandle(usbDevice)) {
        return;
    }

    while(usbDevice->configured &&
            !QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) {
        int byteCount = 0;
        while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue) &&
                byteCount < USB_SEND_BUFFER_SIZE) {
            usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t,
                    &usbDevice->sendQueue);
        }

        int nextByteIndex = 0;
        while(nextByteIndex < byteCount) {
            // Make sure the USB write is 100% complete before messing with this
            // buffer after we copy the message into it - the Microchip library
            // doesn't copy the data to its own internal buffer. See #171 for
            // background on this issue.
            // TODO instead of dropping, replace POP above with a SNAPSHOT
            // and POP off only exactly how many bytes were sent after the
            // fact.
            // TODO in order for this not to fail too often I had to increase
            // the USB_HANDLE_MAX_WAIT_COUNT. that may be OK since now we have
            // VBUS detection.
            if(!waitForHandle(usbDevice)) {
                debug("USB not responding in a timely fashion, dropped data");
                return;
            }

            int bytesToTransfer = min(MAX_USB_PACKET_SIZE_BYTES,
                    byteCount - nextByteIndex);
            usbDevice->deviceToHostHandle = usbDevice->device.GenWrite(
                    usbDevice->inEndpoint,
                    &usbDevice->sendBuffer[nextByteIndex], bytesToTransfer);
            nextByteIndex += bytesToTransfer;
        }
    }
}
Beispiel #13
0
void processCanWriteQueue(CanBus* bus) {
    while(!QUEUE_EMPTY(CanMessage, &bus->sendQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->sendQueue);
        debug("Sending CAN message id = 0x%03x, data = 0x", message.id);
        for(int i = 0; i < 8; i++) {
            debug("%02x ", ((uint8_t*)&message.data)[i]);
        }
        debug("\r\n");
        if(bus->writeHandler == NULL) {
            debug("No function available for writing to CAN -- dropped");
        } else if(!bus->writeHandler(bus, message)) {
            debug("Unable to send CAN message with id = 0x%x\r\n", message.id);
        }
    }
}
Beispiel #14
0
uint32_t _process( struct iothreads * parent, struct iothread * thread, struct taskqueue * doqueue )
{
    uint32_t nprocess = 0;

    // 交换任务队列
    msgqueue_swap( thread->queue, doqueue );

    // 获取最大任务数
    nprocess = QUEUE_COUNT(taskqueue)(doqueue);

    // 处理任务
    while ( QUEUE_COUNT(taskqueue)(doqueue) > 0 )
    {
        struct task task;
        void * data = NULL;

        QUEUE_POP(taskqueue)( doqueue, &task );
        switch ( task.type )
        {
            case eTaskType_Null :
                {
                    // 空命令
                    continue;
                }
                break;

            case eTaskType_User :
                {
                    // 用户命令
                    data = task.taskdata;
                }
                break;

            case eTaskType_Data :
                {
                    // 数据命令
                    data = (void *)(task.data);
                }
                break;
        }

        // 回调
        parent->method( parent->context, thread->index, task.utype, data );
    }

    return nprocess;
}
Beispiel #15
0
/*Destruye un arbol y libera toda la memoria de sus elementos
*/
void network_destroy(AbbNet net){
	networkNode * pivote;
	QUEUE = elem_list;
	elem_list = QUEUE_CREATE();
	QUEUE_ADD(elem_list, net->tree);/*mete la copa del arbol en la cola*/
	while(!QUEUE_ISEMPTY(elem_list)){
		pivote = QUEUE_HEAD(elem_list);
		/*mete a los hijos de pivote a la cola si no son hojas*/
		if (pivote.left != Leaf)
			QUEUE_ADD(pivote.left);
		if (pivote.rigth != Leaf)
			QUEUE_ADD(pivote.rigth);
		/*elimina pivote*/
		edgeNode_destroy(pivote->edge);
		free(pivote);
		QUEUE_POP(elem_list);
		net->cant -= 1;
	}
}
Beispiel #16
0
unsigned int _read(struct Process *proc) {
	struct Process *wakeproc;
	size_t buf_size = (size_t)proc->stackptr[2+0];
	size_t msg_size;
	char *buf = (char*)proc->stackptr[2+1];
	msg_size = pipe_pop_message(&(proc->msgs),buf_size,buf);
	if(msg_size == 0) {
		/* not enough data to complete the read */
		proc->blocked = (unsigned int)&_read;
	} else {
		proc->stackptr[2+0] = msg_size; /* return number of bytes in the message */
		/* unblock writers */
		if(QUEUE_LEN(proc->writers) > 0) {
			QUEUE_POP(proc->writers,wakeproc);
			wakeproc->blocked = 0;
			_write(wakeproc,proc);
		}
	}
	return proc->blocked;
}
Beispiel #17
0
static void
aggregate_func (GstAggregator * self)
{
  GstAggregatorPrivate *priv = self->priv;
  GstAggregatorClass *klass = GST_AGGREGATOR_GET_CLASS (self);

  if (self->priv->running == FALSE) {
    GST_DEBUG_OBJECT (self, "Not running anymore");

    return;
  }

  QUEUE_POP (self);

  GST_LOG_OBJECT (self, "Checking aggregate");
  while (priv->send_eos && gst_aggregator_iterate_sinkpads (self,
          (GstAggregatorPadForeachFunc)
          _check_all_pads_with_data_or_eos_or_timeout, NULL) && priv->running) {
    GST_TRACE_OBJECT (self, "Actually aggregating!");

    priv->flow_return = klass->aggregate (self);

    if (priv->flow_return == GST_FLOW_EOS) {
      QUEUE_FLUSH (self);
      _push_eos (self);
    }

    if (priv->flow_return == GST_FLOW_FLUSHING &&
        g_atomic_int_get (&priv->flush_seeking))
      priv->flow_return = GST_FLOW_OK;

    GST_LOG_OBJECT (self, "flow return is %s",
        gst_flow_get_name (priv->flow_return));

    if (priv->flow_return != GST_FLOW_OK)
      break;
  }

}
Beispiel #18
0
/* start client transaction state */
int conn_start_cstate(CONN *conn)
{
    CHUNK *cp = NULL;
    int ret = -1;
    /* Check connection and transaction state */
    CONN_CHECK_RET(conn, -1);

    if(conn)
    {
        if(conn->c_state == C_STATE_FREE)
        {
            conn->c_state = C_STATE_USING;
            while(QUEUE_POP(conn->send_queue, PCHUNK, &cp) == 0){CK_CLEAN(cp);}
            MB_RESET(conn->packet);
            MB_RESET(conn->cache);
            MB_RESET(conn->buffer);
            MB_RESET(conn->oob);
            CK_RESET(conn->chunk);
            ret = 0;
        }
    }
    return ret;
}
Beispiel #19
0
void handleTransmitInterrupt() {
    disableTransmitInterrupt();

    if(CTS_STATE == INACTIVE) {
        return;
    }

    while(UART_CheckBusy(UART1_DEVICE) == SET);

    while(!QUEUE_EMPTY(uint8_t, &listener.serial->sendQueue)) {
        uint8_t byte = QUEUE_PEEK(uint8_t, &listener.serial->sendQueue);
        if(UART_Send(UART1_DEVICE, &byte, 1, NONE_BLOCKING)) {
            QUEUE_POP(uint8_t, &listener.serial->sendQueue);
        } else {
            break;
        }
    }

    if(QUEUE_EMPTY(uint8_t, &listener.serial->sendQueue)) {
        disableTransmitInterrupt();
    } else {
        enableTransmitInterrupt();
    }
}
Beispiel #20
0
/* Private: Flush any queued data out to the USB host. */
static void sendToHost(UsbDevice* usbDevice) {
    if(!usbDevice->configured) {
        return;
    }

    uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint();
    Endpoint_SelectEndpoint(IN_ENDPOINT_NUMBER);
    if(!Endpoint_IsINReady() || QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) {
        return;
    }

    // get bytes from transmit FIFO into intermediate buffer
    int byteCount = 0;
    while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)
            && byteCount < USB_SEND_BUFFER_SIZE) {
        usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue);
    }

    if(byteCount > 0) {
        Endpoint_Write_Stream_LE(usbDevice->sendBuffer, byteCount, NULL);
    }
    Endpoint_ClearIN();
    Endpoint_SelectEndpoint(previousEndpoint);
}
Beispiel #21
0
} END_TEST

START_TEST(test_queue_pop) {
    struct msg *msgs;
    struct msg src1, src2, src3, *dst1, *dst2, *dst3;

    QUEUE_INIT(struct msg, msgs);

    src1.content = "abc";
    src2.content = "def";
    src3.content = "ghi";

    QUEUE_PUSH(msgs, &src1);

    QUEUE_POP(msgs, dst1);
    ck_assert_ptr_eq(dst1, &src1);
    ck_assert_ptr_eq(msgs->qh.qc->front, NULL);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src1); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src1.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 0);
    ck_assert_ptr_eq(dst1->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src1.content, dst1->content);

    QUEUE_PUSH(msgs, &src1);
    QUEUE_PUSH(msgs, &src2);
    QUEUE_POP(msgs, dst1);
    ck_assert_ptr_eq(dst1, &src1);
    ck_assert_ptr_eq(msgs->qh.qc->front, &src2);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src2); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src2.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 1);
    ck_assert_ptr_eq(dst1->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src1.content, dst1->content);
    QUEUE_POP(msgs, dst2);
    ck_assert_ptr_eq(dst2, &src2);
    ck_assert_ptr_eq(msgs->qh.qc->front, NULL);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src2); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src2.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 0);
    ck_assert_ptr_eq(dst2->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src2.content, dst2->content);

    QUEUE_PUSH(msgs, &src1);
    QUEUE_PUSH(msgs, &src2);
    QUEUE_PUSH(msgs, &src3);
    QUEUE_POP(msgs, dst1);
    ck_assert_ptr_eq(dst1, &src1);
    ck_assert_ptr_eq(msgs->qh.qc->front, &src2);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src3); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src3.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 2);
    ck_assert_ptr_eq(dst1->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src1.content, dst1->content);
    QUEUE_POP(msgs, dst2);
    ck_assert_ptr_eq(dst2, &src2);
    ck_assert_ptr_eq(msgs->qh.qc->front, &src3);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src3); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src3.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 1);
    ck_assert_ptr_eq(dst2->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src2.content, dst2->content);
    QUEUE_POP(msgs, dst3);
    ck_assert_ptr_eq(dst3, &src3);
    ck_assert_ptr_eq(msgs->qh.qc->front, NULL);
    ck_assert_ptr_eq(msgs->qh.qc->back, &src3); // unchanged w/ pop
    ck_assert_ptr_eq(msgs->qh.qc->backqh, &src3.qh); // unchanged w/ pop
    ck_assert_uint_eq(msgs->qh.qc->size, 0);
    ck_assert_ptr_eq(dst3->qh.next, msgs->qh.qc->front);
    ck_assert_str_eq(src3.content, dst3->content);

    QUEUE_FREE(msgs);
} END_TEST