Пример #1
0
u32 bus_ita_return(u32 adapterId, u32 desId, u8 ita_session, u32 data_len, u8 *data)
{
	if (data_len > BUS_PACKAGE_MAX_LEN)
	{
		return ERR_BUG_OCCURE;
	}
	u32 code = 0;
	bus_os_sem sem;
	code = ack_map_set(adapterId,desId, ita_session, &sem);
	if (code)
	{
		return code;
	}
	bus_os_create_sem(&sem, 0);

	for (int x = 0; x < 3; x++)
	{
		bus_simple_send(adapterId, desId, BUS_PACK_FUNC_RETURN, ita_session, data_len, data);
		//----------------- 到这里已经全部发送完数据 ----------------------
		if (bus_os_pend_sem(&sem, BUS_RET_ACK_TIMOUT) == 0)
		{
			// 收到了ack 直接跳过去
			bus_os_del_sem(&sem);
			goto FOUND;
		}
	}
	ack_map_erase(adapterId, desId, ita_session);
	BUS_LOG("ERR_BUS_RETURN_NO_ACK\r\n");
	return ERR_BUS_RETURN_NO_ACK;
FOUND:
	ack_map_erase(adapterId, desId, ita_session);
	return 0;
}
Пример #2
0
//--------------- 下面是给驱动调用的函数         -----------------------------------------------------------
void bus_for_driver_call(u32 adapterId, u32 srcId, u32 desId, u32 functionId, u32 sessionId, u32 data_len, u8 *data)
{
	//bus_frame frame;
	//frame.adapterId = adapterId;
	//frame.srcId = srcId;
	//frame.desId = desId;
	//frame.functionId = functionId;
	//frame.sessionId = sessionId;
	//frame.data_len = data_len;
	//memmove(frame.data, data, data_len);
	if (frame_q.size >= 16)		//队列满 直接忽略
	{
		BUS_LOG("frame queu full \r\n");
		return;
	}

	bus_frame *frame = &frame_q.q[frame_q.writeIdx++];
	frame->adapterId = adapterId;
	frame->srcId = srcId;
	frame->desId = desId;
	frame->functionId = functionId;
	frame->sessionId = sessionId;
	frame->data_len = data_len;
	memmove(frame->data, data, data_len);
	frame_q.size++;
	bus_os_post_sem(&frame_q.sem);

	// 	BUS_LOG("RX : ");
// 	for (int i = 0; i < sizeof(frame); i++)
// 	{
// 		BUS_LOG("%02X ", ((u8*)&frame)[i]);
// 	}
// 	BUS_LOG("\r\n");
//	bus_insert_frame(&frame);
}
Пример #3
0
static bool sink_socket_read(struct bus *b,
                             listener *l, connection_info *ci, ssize_t size) {
    BUS_LOG_SNPRINTF(b, 3, LOG_LISTENER, b->udata, 64,
                     "read %zd bytes, calling sink CB", size);

#if DUMP_READ
    printf("\n");
    for (int i = 0; i < size; i++) {
        if (i > 0 && (i & 15) == 0) {
            printf("\n");
        }
        printf("%02x ", l->read_buf[i]);
    }
    printf("\n\n");
#endif

    bus_sink_cb_res_t sres = b->sink_cb(l->read_buf, size, ci->udata);
    if (sres.full_msg_buffer) {
        BUS_LOG(b, 3, LOG_LISTENER, "calling unpack CB", b->udata);
        bus_unpack_cb_res_t ures = b->unpack_cb(sres.full_msg_buffer, ci->udata);
        BUS_LOG_SNPRINTF(b, 3, LOG_LISTENER, b->udata, 64,
                         "process_unpacked_message: ok? %d, seq_id:%lld",
                         ures.ok, (long long)ures.u.success.seq_id);
        process_unpacked_message(l, ci, ures);
    }

    ci->to_read_size = sres.next_read;

    BUS_LOG_SNPRINTF(b, 3, LOG_LISTENER, b->udata, 64,
                     "expecting next read to have %zd bytes", ci->to_read_size);

    /* Grow read buffer if necessary. */
    if (ci->to_read_size > l->read_buf_size) {
        if (!ListenerTask_GrowReadBuf(l, ci->to_read_size)) {
            BUS_LOG_SNPRINTF(b, 3, LOG_MEMORY, b->udata, 128,
                             "Read buffer realloc failure for %p (%zd to %zd)",
                             l->read_buf, l->read_buf_size, ci->to_read_size);
            BUS_ASSERT(b, b->udata, false);
        }
    }
    return true;
}
Пример #4
0
static bool do_blocking_connection(struct bus *b, SSL *ssl, int fd) {
    BUS_LOG_SNPRINTF(b, 2, LOG_SOCKET_REGISTERED, b->udata, 128,
        "SSL_Connect handshake for socket %d", fd);

    struct pollfd fds[1];
    fds[0].fd = fd;
    fds[0].events = POLLOUT;
    
    bool connected = false;
    size_t elapsed = 0;

    while (!connected) {
        int pres = syscall_poll(fds, 1, TIMEOUT_MSEC);
        BUS_LOG_SNPRINTF(b, 5, LOG_SOCKET_REGISTERED, b->udata, 128,
            "SSL_Connect handshake for socket %d, poll res %d", fd, pres);

        if (pres < 0) {
            if (Util_IsResumableIOError(errno)) {
                errno = 0;
            } else {
                /*  */
                assert(false);
            }
        } else if (pres > 0) {
            if (fds[0].revents & (POLLOUT | POLLIN)) {
                int connect_res = SSL_connect(ssl);
                BUS_LOG_SNPRINTF(b, 5, LOG_SOCKET_REGISTERED, b->udata, 128,
                    "socket %d: connect_res %d", fd, connect_res);

                if (connect_res == 1) {
                    BUS_LOG_SNPRINTF(b, 5, LOG_SOCKET_REGISTERED, b->udata, 128,
                        "socket %d: successfully connected", fd);
                    connected = true;
                } else if (connect_res < 0) {
                    int reason = SSL_get_error(ssl, connect_res);

                    switch (reason) {
                    case SSL_ERROR_WANT_WRITE:
                        BUS_LOG(b, 4, LOG_SOCKET_REGISTERED, "WANT_WRITE", b->udata);
                        fds[0].events = POLLOUT;
                        break;
                        
                    case SSL_ERROR_WANT_READ:
                        BUS_LOG(b, 4, LOG_SOCKET_REGISTERED, "WANT_READ", b->udata);
                        fds[0].events = POLLIN;
                        break;
                        
                    case SSL_ERROR_SYSCALL:
                    {
                        if (Util_IsResumableIOError(errno)) {
                            errno = 0;
                            break;
                        } else {
                            unsigned long errval = ERR_get_error();
                            char ebuf[256];
                            BUS_LOG_SNPRINTF(b, 1, LOG_SOCKET_REGISTERED, b->udata, 128,
                                "socket %d: ERROR -- %s", fd, ERR_error_string(errval, ebuf));
                        }
                    }
                    break;
                    default:
                    {
                        unsigned long errval = ERR_get_error();
                        char ebuf[256];
                        BUS_LOG_SNPRINTF(b, 1, LOG_SOCKET_REGISTERED, b->udata, 128,
                            "socket %d: ERROR %d -- %s", fd, reason, ERR_error_string(errval, ebuf));
                        assert(false);
                    }
                    }

                } else {
                    BUS_LOG_SNPRINTF(b, 5, LOG_SOCKET_REGISTERED, b->udata, 128,
                        "socket %d: unknown state, setting event bask to (POLLIN | POLLOUT)",
                        fd);
                    fds[0].events = (POLLIN | POLLOUT);
                }
            } else if (fds[0].revents & POLLHUP) {
                BUS_LOG_SNPRINTF(b, 1, LOG_SOCKET_REGISTERED, b->udata, 128,
                    "SSL_Connect: HUP on %d", fd);
                return false;
            } else if (fds[0].revents & POLLERR) {
                BUS_LOG_SNPRINTF(b,12, LOG_SOCKET_REGISTERED, b->udata, 128,
                    "SSL_Connect: ERR on %d", fd);
                return false;
            }
        } else {
            BUS_LOG(b, 4, LOG_SOCKET_REGISTERED, "poll timeout", b->udata);
            elapsed += TIMEOUT_MSEC;
            if (elapsed > MAX_TIMEOUT) {
                BUS_LOG(b, 2, LOG_SOCKET_REGISTERED, "timed out", b->udata);
                return false;
            }
        }
    }
    
    return connected;
}
Пример #5
0
//发送数据 发送完毕一直等待数据返回 或者心跳维持
u32 bus_ita_send(u32 adapterId, u32 desId, u32 data_len, u8 *data, u8 *dataout, u32 *dataoutLen,u32 timeOut)
{
	u32 code = 0;
	u8 session = bus_session_id++;
	//检查包长度
	if (data_len > BUS_PACKAGE_MAX_LEN)
	{
		code = ERR_BUG_OCCURE;
		return code;
	}
	bus_os_sem sem;
	code = ack_map_set(adapterId,desId, session, &sem);
	if (code)
	{
		return code;
	}
	bus_os_create_sem(&sem, 0);

	for (int x = 0; x < 3; x++)
	{
		bus_simple_send(adapterId, desId, BUS_PACK_FUNC_SEND, session, data_len, data);
		//----------------- 到这里已经全部发送完数据 ----------------------
		if (bus_os_pend_sem(&sem, BUS_WAITE_ACK_TIME) == 0)
		{
			// 收到了ack 直接跳过去
			bus_os_del_sem(&sem);
			goto FIND_ACK;
		}
		else
		{
			BUS_LOG("waite ack timeout\r\n");
		}
	}
	ack_map_erase(adapterId, desId, session);	//不管怎样 都要删掉
	BUS_LOG("send but no ack\r\n");
	return ERR_BUS_ITA_NO_ACK;
FIND_ACK:
	ack_map_erase(adapterId, desId, session);	//不管怎样 都要删掉
	for (int i =0;i<timeOut;i++)
	{
		u8 funcOut = 0;
		if (retHandleCnt > 0)
		{
			u8 find = 0;
			CPU_DEF();
			CPU_PEND();
			find = bus_find_packet_data(adapterId, desId, session, BUS_PACK_FUNC_RETURN, &funcOut, dataout, dataoutLen);
			if (find)
			{
				retHandleCnt--;
			}
			CPU_POST();
			if (find)
			{
				//在给一个ACK包 告诉接收端return 接收完全成功
				bus_simple_send(adapterId, desId, BUS_PACK_FUNC_ACK, session, 0, NULL);
				return 0;
			}
			else
			{
				bus_os_sleep(1);
			}
		}
		else
		{
			bus_os_sleep(1);	//10ms 之后 在查看 给其他线程工作时间
		}
	}
	BUS_LOG("ERR_BUS_REPONSE_ACK_TIMOUT\r\n");
	return ERR_BUS_REPONSE_ACK_TIMOUT;
}
Пример #6
0
//队列等待线程
void rx_packet_thread(void *data)
{
	while (1)
	{
		bus_os_pend_sem(&frame_q.sem, 0);
		if (frame_q.size > 0)
		{
			//BUS_LOG("get a frame\r\n");
			//从一级队列里面移动到数据结构里面去
			bus_frame *frame = &frame_q.q[frame_q.readIdx++];
			//看下这个帧是不是应答帧 如果是的 那么直接post就完了
			if (frame->functionId == BUS_PACK_FUNC_ACK)
			{
				ack_map_post(frame->adapterId, frame->srcId, frame->sessionId);
				frame_q.size--;
				continue;
			}
			bus_put_frame(frame);
			frame_q.size--;
			//不断的寻找发送包 并且进行调用接收回调函数
			if (rxHanleCnt > 0)
			{
				CPU_DEF();
				PacketNode * get;
				CPU_PEND();
				get = bus_get_packet();
				CPU_POST();
				if (get)
				{
					rxHanleCnt--;
					if (packet_q.size < 16)
					{
						bus_packet *packet = &packet_q.q[packet_q.writeIdx];
						packet_q.writeIdx++;
						u8 * data = my_malloc(get->packetLen);
						//BUS_LOG("packlen = %d\r\n", get->packetLen);
						packet->data = data;
						packet->data_len = get->packetLen;
						packet->adapterId = get->frameList->frame.adapterId;
						packet->srcId = get->frameList->frame.srcId;
						packet->desId = get->frameList->frame.desId;
						packet->sessionId = get->frameList->frame.sessionId;
						packet->functionId = get->frameList->frame.functionId;

						CPU_PEND();
						for (FrameNode *fp = get->frameList; fp != NULL;)
						{
							int frameIdx = ReadU16(fp->frame.data);		//获取 帧索引
							int frameLen = fp->frame.data_len - 2;		//获取 数据长度 除掉帧索引

							if (frameIdx != 0)	// 第一帧不能做操作的
							{
								for (int i = 0; i < frameLen; i++)
								{
									data[(frameIdx - 1) * 6 + i] = fp->frame.data[i + 2];
								}
							}
							//这个节点要删除
							FrameNode *temp = fp;
							fp = fp->next;
							my_free(temp);
						}
						//把包引用也要free掉
						my_free(get);
						//压到 packet队列里面去 然后给信号量

						packet_q.size++;
						bus_os_post_sem(&packet_q.sem);
						CPU_POST();
					}
					else
					{
						BUS_LOG("call back queue full\r\n");
					}
				}
			}
		}
	}
}
Пример #7
0
void ListenerIO_AttemptRecv(listener *l, int available) {
    /*   --> failure --> set 'closed' error on socket, don't die */
    struct bus *b = l->bus;
    int read_from = 0;
    BUS_LOG(b, 3, LOG_LISTENER, "attempting receive", b->udata);

    for (int i = 0; i < l->tracked_fds; i++) {
        if (read_from == available) {
            break;
        }
        struct pollfd *fd = &l->fds[i + INCOMING_MSG_PIPE];
        connection_info *ci = l->fd_info[i];
        BUS_ASSERT(b, b->udata, ci->fd == fd->fd);

        BUS_LOG_SNPRINTF(b, 1, LOG_LISTENER, b->udata, 64,
                         "poll: l->fds[%d]->revents: 0x%04x",  // NOCOMMIT
                         i + INCOMING_MSG_PIPE, fd->revents);

        /* If a socket is about to be shut down, we want to get a
         * complete read from it if possible, because it's likely to be
         * an UNSOLICITEDSTATUS message with a reason for the hangup.
         * Only do single reads otherwise, though, otherwise the
         * listener can end up blocking too long handling consecutive
         * reads on a busy connection and causing the incoming command
         * queue to get backed up. */
        bool is_closing = fd->events & (POLLERR | POLLNVAL | POLLHUP);

        if (fd->revents & POLLIN) {
            // Try to read what we can (possibly before hangup)
            ssize_t cur_read = 0;
            size_t to_read = ci->to_read_size;
            do {
                BUS_LOG_SNPRINTF(b, 3, LOG_LISTENER, b->udata, 64,
                                 "reading %zd bytes from socket (buf is %zd)",
                                 ci->to_read_size, l->read_buf_size);
                BUS_ASSERT(b, b->udata, l->read_buf_size >= to_read);

                switch (ci->type) {
                case BUS_SOCKET_PLAIN:
                    cur_read = socket_read_plain(b, l, i, ci);
                    break;
                case BUS_SOCKET_SSL:
                    cur_read = socket_read_ssl(b, l, i, ci);
                    break;
                default:
                    BUS_ASSERT(b, b->udata, false);
                }
                // -1: socket error
                // 0: no more to read
            } while (is_closing && cur_read > 0 && ci->to_read_size > 0);
            read_from++;
        }

        if (fd->revents & (POLLERR | POLLNVAL)) {
            read_from++;
            BUS_LOG(b, 2, LOG_LISTENER,
                    "pollfd: socket error (POLLERR | POLLNVAL)", b->udata);
            set_error_for_socket(l, i, ci->fd, RX_ERROR_POLLERR);
        } else if (fd->revents & POLLHUP) {
            read_from++;
            BUS_LOG(b, 3, LOG_LISTENER, "pollfd: socket error POLLHUP",
                    b->udata);
            set_error_for_socket(l, i, ci->fd, RX_ERROR_POLLHUP);
        }
    }

    if (l->error_occured) {  // only conditionally do this to avoid wasting CPU
        /* This is done outside of the polling loop, to avoid erroneously repeat-polling
         * or skipping any individual file descriptors. */
        move_errored_active_sockets_to_end(l);
        l->error_occured = false;
    }
}
Пример #8
0
bool BusPoll_OnCompletion(struct bus *b, int fd) {
    /* POLL in a pipe */
    #ifndef TEST
    struct pollfd fds[1];
    #endif
    fds[0].fd = fd;
    fds[0].events = POLLIN;

    for (;;) {
        BUS_LOG(b, 5, LOG_SENDING_REQUEST, "Polling on completion...tick...", b->udata);
        #ifdef TEST
        errno = poll_errno;
        #endif
        BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
            "poll_on_completion, polling %d", fd);
        int res = syscall_poll(fds, 1, -1);
        BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
            "poll_on_completion for %d, res %d (errno %d)", fd, res, errno);
        if (res == -1) {
            if (Util_IsResumableIOError(errno)) {
                BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion, resumable IO error %d", errno);
                errno = 0;
                continue;
            } else {
                BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion, non-resumable IO error %d", errno);
                return false;
            }
        } else if (res == 1) {
            uint16_t msec = 0;
            #ifndef TEST
            uint8_t read_buf[sizeof(uint8_t) + sizeof(uint16_t)];
            #endif

            if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
                BUS_LOG(b, 1, LOG_SENDING_REQUEST, "failed (broken alert pipe)", b->udata);
                return false;
            }

            BUS_LOG(b, 3, LOG_SENDING_REQUEST, "Reading alert pipe...", b->udata);
            #ifdef TEST
            errno = read_errno;
            #endif
            ssize_t sz = syscall_read(fd, read_buf, sizeof(read_buf));

            if (sz == sizeof(read_buf)) {
                /* Payload: little-endian uint16_t, msec of backpressure. */
                assert(read_buf[0] == LISTENER_MSG_TAG);

                msec = (read_buf[1] << 0) + (read_buf[2] << 8);
                Bus_BackpressureDelay(b, msec, LISTENER_BACKPRESSURE_SHIFT);
                BUS_LOG(b, 4, LOG_SENDING_REQUEST, "sent!", b->udata);
                return true;
            } else if (sz == -1) {
                if (Util_IsResumableIOError(errno)) {
                    BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
                        "poll_on_completion read, resumable IO error %d", errno);
                    errno = 0;
                    continue;
                } else {
                    BUS_LOG_SNPRINTF(b, 2, LOG_SENDING_REQUEST, b->udata, 64,
                        "poll_on_completion read, non-resumable IO error %d", errno);
                    errno = 0;
                    return false;
                }
            } else {
                BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion bad read size %zd", sz);
                return false;
            }
        } else {
            /* This should never happen, but I have seen it occur on OSX.
             * If we log it, reset errno, and continue, it does not appear
             * to fall into busywaiting by always returning 0. */
            BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                "poll_on_completion, blocking forever returned %d, errno %d", res, errno);
            errno = 0;
        }
    }
}