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; }
//--------------- 下面是给驱动调用的函数 ----------------------------------------------------------- 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); }
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; }
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; }
//发送数据 发送完毕一直等待数据返回 或者心跳维持 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; }
//队列等待线程 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"); } } } } } }
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; } }
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; } } }