/*------------------------------------------------------------------------------ | Function : receive_message_ack +------------------------------------------------------------------------------ | Description : | | Parameters : | | Returns : void +----------------------------------------------------------------------------*/ t_tx_event receive_message_ack(void) { receive_message_header(FALSE); if(rx_header.fields.ctrl && rx_header.fields.ack && !rx_header.fields.length) { return tx_header.fields.more ? tx_event_more : tx_event_no_more; } else { DEBUG_LOGF_ERROR("USB: Expected ACK but received MSG"); return tx_event_done; } }
// Handle each peer connection in their own handlers void *client_connection_handler(void *metadata) { struct connection_details * cd = (struct connection_details*) metadata; struct message_header mh; while (1) { receive_message_header(cd->serving_fd, &mh); // FIXME: The condition where socket server gets a connection // from the peer but the user didn't allocate a SocketChannel // for the peer.This can even happen if adapter is instantiated // first and SocketChannel is allocated for the peer subsequently // For now assume the user will maintain the right order i.e // allocate a SocketChannel for all peers and then instantiate // the adapter. /* if(cd->sa->channels.size() < mh.rank || cd->sq->channels.at(mh.rank) == NULL){ printf("ERROR:No SocketChannel assigned for the peer with rank [%d]...terminating the thread handler\n", mh.rank); // FIXME: Notify the client and exit pthread_exit(); } */ // From the peer rank locate the local SocketChannel for that // peer and sets it's serving_fd SocketChannel* sc = cd->sa->channels->at(mh.rank).get(); sc->serving_fd = cd->serving_fd; uint8_t* read_buffer = new uint8_t[mh.size]; uint8_t* marker = read_buffer; int cur_cnt = 0; int max_buff = 0; while (cur_cnt < mh.size) { if ((mh.size - cur_cnt) > 256) max_buff = 256; else max_buff = mh.size - cur_cnt; int n = read(sc->serving_fd, marker, max_buff); CHECK(n >= 0) << "ERROR: Reading data from client"; marker = marker + n; cur_cnt = cur_cnt + n; } // Wrap the received message in an object QueuedMessage and // push it to the local receive queue of the peer's // SocketChannel QueuedMessage* mq = new QueuedMessage(mh.type, mh.size, read_buffer); if(mh.type == DIFF) sc->receive_queue.push(mq); else sc->receive_queue_ctrl.push(mq); } return NULL; }
/*------------------------------------------------------------------------------ | Function : rx_usb +------------------------------------------------------------------------------ | Description : | | Parameters : | | Returns : void +----------------------------------------------------------------------------*/ void rx_usb(t_rx_event event) { do { LOGF("USB RX: %s - %s", rx_state_names[rx_state], rx_events[event]); switch(rx_state) { case rx_state_null: switch(event) { case rx_event_init: rx_state = rx_state_idle; event = rx_event_done; break; } break; case rx_state_idle: switch(event) { case rx_event_receive: if(tx_state == tx_state_idle) { rx_state = rx_state_awaiting_header; event = receive_message_header(TRUE); } else { rx_state = rx_state_pending; event = rx_event_done; } break; case rx_event_tx_idle: event = rx_event_done; break; } break; case rx_state_pending: switch(event) { case rx_event_more: case rx_event_tx_idle: rx_state = rx_state_awaiting_header; event = receive_message_header(TRUE); break; case rx_event_receive: event = rx_event_done; break; } break; case rx_state_awaiting_header: switch(event) { case rx_event_header_received: rx_state = rx_state_awaiting_data; event = receive_message_data(); break; case rx_event_header_failed: rx_state = rx_state_idle; event = rx_event_done; break; } break; case rx_state_awaiting_data: switch(event) { case rx_event_data_received: event = check_more_data(); if(event == rx_event_more) { rx_state = rx_state_pending; } else { rx_state = rx_state_idle; tx_usb(tx_event_rx_idle); } deliver_message_data(); break; case rx_event_data_failed: rx_state = rx_state_idle; event = rx_event_done; break; } break; } } while(event != rx_event_done); }