void* read_message(int fd){ char header_buff[HEADER_SIZE]; char* message_buffer; char* mess_type; int *file_id, *part_size_int = 0; int mess_size; int c = 0; void* return_value; int i = 0; //header_buff = malloc(HEADER_SIZE); if((c = bulk_read(fd, header_buff, HEADER_SIZE)) != HEADER_SIZE) { if(c < 0) ERR("read"); } mess_type = strtok(header_buff, "+"); mess_size = atoi(strtok(NULL, "+")); message_buffer = malloc(mess_size); while((c = bulk_read(fd, message_buffer, mess_size)) != mess_size) { if(c < 0) ERR("read"); } //sprintf(message, "%s", message_buffer); printf("\n\n\n\nOTRZYMANA WIADOMOŚĆ: %s\n", message_buffer); switch(*mess_type) { case 82: part_size_int = malloc(1); *part_size_int = atoi(message_buffer); printf("Rozmiar wiadomości: %d\n", *part_size_int); return_value = (void*) part_size_int; break; case 70: file_id = malloc(1); *file_id = atoi(message_buffer); printf("Przysłany id pliku: %d", *file_id); return_value = (void*) file_id; break; } //free(header_buff); free(message_buffer); return return_value; }
// Clear all incoming data that's already waiting somewhere in kernel buffers // and discard it. void flush_incoming(struct clock_connection *clk) { // When bulk_read times out errno = ETIMEDOUT=110, retval =-1 // should we check for this? while(bulk_read(clk) >= 0) { // TODO: fail nicely if waiting too long to avoid hangs } }
// Preliminary rough sync with a single message - CMD_SYNC_ZERO = 'Z'. // This is not strictly necessary but greatly simplifies debugging // by removing the need to look at very long numbers. void zero_remote(struct clock_connection *clk) { flush_incoming(clk); clk->t_base = uptimeMicros(); send_cmd(clk, CMD_SYNC_ZERO); bulk_read(clk); // TODO, make sure we got 'z' clk->maxE = micros(clk); clk->minE = 0; LOGD("Sent a 'Z', reply '%c' in %d us\n", clk->buffer[0], clk->maxE); }
// Ask the remote to send its timestamps // for the digits previously sent to it. void read_remote_timestamps(struct clock_connection *clk, int * times_remote) { int i; int t_remote; // Go over the digits [1, 2 ... 9] for (i = 0; i < 9; i++) { char digit = i + '1'; send_cmd(clk, CMD_SYNC_READOUT); bulk_read(clk); if (clk->buffer[0] != digit) { LOGD("Error, bad reply for R%d: %s", i+1, clk->buffer); } // The reply string looks like digit + space + timestamp // Offset by 2 to ignore the digit and the space t_remote = atoi(clk->buffer + 2); times_remote[i] = t_remote; } }
void improve_maxE(struct clock_connection *clk) { int times_remote_sent[9] = {0}; int times_local_received[9] = {0}; // Tell the remote to send us digits with delays // TODO: try tuning / configuring the delay time on remote side send_async(clk, CMD_SYNC_SEND); // Read and timestamp the incoming digits, they may arrive out of order. // TODO: Try he same with USBDEVFS_REAPURB, it might be faster int i; for (i = 0; i < 9; ++i) { int retval = bulk_read(clk); // TODO: deal with retval = (bytes returned) > 1. shouldn't happen. // Can it happen on some devices? int t_local = micros(clk); int digit = atoi(clk->buffer); if (digit <=0 || digit > 9) { LOGD("Error, bad incoming digit: %s\n", clk->buffer); } times_local_received[digit-1] = t_local; } // Flush whatever came after the digits. As of this writing, it's usually // a single linefeed character. flush_incoming(clk); // Read out the remote timestamps of when the digits were sent read_remote_timestamps(clk, times_remote_sent); // Do stats int maxE = clk->maxE; for (i = 0; i < 9; i++) { int trs = times_remote_sent[i]; int tlr = times_local_received[i]; int dt = tlr - trs; if (tlr != 0 && trs != 0 && dt < maxE) { maxE = dt; } } clk->maxE = maxE; LOGD("E is between %d and %d us\n", clk->minE, clk->maxE); }
/** * Handles incoming communication from clients and passes messages to be served. * @param[in] client_fd File descriptor of a client that is currently served. * @param[in] base_rdfs Bit array holding file descriptors being served by the current thread. * @param[in] tdata Pointer to a structure containing arguments that are used by the thread. * \sa thread_data_s */ void thread_communicate(int client_fd, fd_set *base_rdfs, thread_data_s *tdata) { char buffer[MAX_MSG_SIZE]; ssize_t size; request_s request; pthread_t tid; memset(&request, 0, sizeof(request_s)); tid = pthread_self(); size = bulk_read(client_fd, buffer, MAX_MSG_SIZE); if (size == MAX_MSG_SIZE) { fprintf(stderr, "(Thread %d) Message received from client fd: %d\n", (int) tid, client_fd); string_to_request(buffer, &request); thread_request_handler(client_fd, &request, tdata->game, base_rdfs); } if (size == 0) { fprintf(stderr, "(Thread %d) End of file. Removing player. Closing descriptor: %d\n", (int) tid, client_fd); pthread_mutex_lock(tdata->players_list_mutex); remove_player_from_list2(tdata->players_list, client_fd); update_connected_players(client_fd); pthread_mutex_unlock(tdata->players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) { ERR("close"); } FD_CLR(client_fd, base_rdfs); } if (size < 0) { fprintf(stderr, "(Thread %d) Error. Removing player. Closing descriptor: %d\n", (int) tid, client_fd); pthread_mutex_lock(tdata->players_list_mutex); remove_player_from_list2(tdata->players_list, client_fd); update_connected_players(client_fd); pthread_mutex_unlock(tdata->players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) { ERR("close"); } FD_CLR(client_fd, base_rdfs); } }
FILE *data_import (FILE *in_stream, FILE *out_stream) { char depot[DEPOT_SIZE]; char remainder[200]; char s_key[20]; int r_num = 0; int target_frame; int pos; // The next position in depot to be operated. bool finished, split; while (!feof (in_stream)) { finished = split = false; pos = 0; bulk_read (depot, remainder, &r_num, in_stream); while (!finished) // If depot hasn't been used up, loop again. { //int j = 10; //while (j--){ get_search_key (s_key, depot, pos); target_frame = find_target_frame (*index (hash_func (s_key), out_stream), out_stream); unsigned int pid1 = buffer[target_frame].pid; // debug insert_record (&buffer[target_frame], depot, &pos, &finished, &split, out_stream); assert (pid1 == buffer[target_frame].pid); // debug //} //for (j = 0; j < BUFFER_NUM; j++ ) // printf ("\n\n%d\n%s\n\n", buffer[j].pid, buffer[j].data); if (split) { split_page_insert_again (&buffer[target_frame], depot, &pos, &finished, &split, out_stream); split = false; } } // while (!finished) pos = 0; // debug } // while (!feof (in_stream)) return out_stream; }
/** * Reads data from a client socket and passes forward to handle a message or removes a player * and closes socket. * @param[in] client_fd File descriptor of a client that is currently served. * @param base_rdfs Bit array holding file descriptors to be served by the server. * @param players_list Pointer to a list holding players. * @param games_list Pointer to a list holding games. * @param threads_list Pointer to a list holding threads. * @param players_list_mutex Pointer to a mutex guarding players list. * @param games_list_mutex Pointer to a mutex guarding games list. * @param threads_list_mutex Pointer to a mutex guarding threads list. */ void communicate(int client_fd, fd_set *base_rdfs, players_list_s **players_list, games_list_s **games_list, threads_list_s **threads_list, pthread_mutex_t *players_list_mutex, pthread_mutex_t *games_list_mutex, pthread_mutex_t *threads_list_mutex) { char buffer[MAX_MSG_SIZE]; ssize_t size; request_s request; memset(&request, 0, sizeof(request_s)); size = bulk_read(client_fd, buffer, MAX_MSG_SIZE); if (size == MAX_MSG_SIZE) { fprintf(stderr, "Message received from fd: %d\n", client_fd); string_to_request(buffer, &request); request_handler(client_fd, &request, base_rdfs, players_list, games_list, threads_list, players_list_mutex, games_list_mutex, threads_list_mutex); } if (size == 0) { fprintf(stderr, "End of file. Removing player. Closing descriptor: %d\n", client_fd); pthread_mutex_lock(players_list_mutex); remove_player_from_list2(players_list, client_fd); pthread_mutex_unlock(players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) ERR("close"); FD_CLR(client_fd, base_rdfs); } if (size < 0) { fprintf(stderr, "Error. Removing player. Closing descriptor: %d\n", client_fd); pthread_mutex_lock(players_list_mutex); remove_player_from_list2(players_list, client_fd); pthread_mutex_unlock(players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) ERR("close"); FD_CLR(client_fd, base_rdfs); } }
/** * Main function of the server application. It does a infinite loop unless a user exits the program. * @param[in] listener_socket File descriptor of the socket listening incoming connections. * @param[in] fifo File descriptor of a temporary FIFO file. */ void doServer(int listener_socket, int fifo) { int i, fdmax, newfd; players_list_s *players_list = NULL; games_list_s *games_list = NULL; threads_list_s *threads_list = NULL; pthread_mutex_t players_list_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t games_list_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t threads_list_mutex = PTHREAD_MUTEX_INITIALIZER; fd_set base_rdfs, rdfs; sigset_t mask, oldmask; FD_ZERO(&base_rdfs); FD_SET(listener_socket, &base_rdfs); fdmax = max(listener_socket, fifo); sigemptyset(&mask); sigaddset(&mask, SIGINT); sigprocmask(SIG_BLOCK, &mask, &oldmask); initialize_structures(&players_list, &games_list, &threads_list); printf("Four-in-a-line server started\n"); while (work) { rdfs = base_rdfs; if (pselect(fdmax + 1, &rdfs, NULL, NULL, NULL, &oldmask) > 0) { for (i = 0; i <= fdmax; i++) { newfd = -1; if (FD_ISSET(i, &rdfs)) { if (i == listener_socket) { /* request from newly connected client */ newfd = add_new_client(listener_socket); if (newfd > 0) { FD_SET(newfd, &base_rdfs); if (newfd > fdmax) { fdmax = newfd; } display_log(newfd); communicate(newfd, &base_rdfs, &players_list, &games_list, &threads_list, &players_list_mutex, &games_list_mutex, &threads_list_mutex); } else if (i == fifo) { /* trick to update base_rdfs set */ char temp[1]; bulk_read(fifo, temp, 1); } } else { /* request from already connected client */ communicate(i, &base_rdfs, &players_list, &games_list, &threads_list, &players_list_mutex, &games_list_mutex, &threads_list_mutex); } } } } else { if (EINTR == errno) continue; ERR("pselect"); } } pthread_mutex_destroy(&players_list_mutex); pthread_mutex_destroy(&games_list_mutex); pthread_mutex_destroy(&threads_list_mutex); destroy_players(players_list); destroy_games(games_list); destroy_threads(threads_list); sigprocmask(SIG_UNBLOCK, &mask, NULL); }
int main(int argc, char **argv) { const char *mode = "CGRAY"; int resolution = 100; if(argc > 1) { switch(*argv[1]) { case 'c': mode = "CGRAY"; break; case 'g': mode = "GRAY64"; break; case 't': mode = "TEXT"; break; case '-': mode = NULL; break; default: fprintf(stderr, "ERROR: unrecognised mode, " "should be one of [cgt]\n"); return 1; } } if(argc > 2) { resolution = atoi(argv[2]); if(resolution < 100 || resolution > 600 || resolution % 100) { fprintf(stderr, "ERROR: resolution must be a positive " "multiple of 100 no greater than 600\n"); return 1; } } libusb_context *context; libusb_init(&context); device_handle = libusb_open_device_with_vid_pid(context, VID, PID); if(!device_handle) { fprintf(stderr, "ERROR: Unable to find device " "(Vendor ID = %04x, Product ID = %04x)\n", VID, PID); return 1; } libusb_claim_interface(device_handle, 0); libusb_set_interface_alt_setting(device_handle, 0, 0); control_in_vendor_device(1, 2, 0, 255); /* returns 05 10 01 02 00 */ if(mode) { char *config = build_config( mode, MIN(resolution, 300), resolution, PAGE_WIDTH * MIN(resolution, 300)/100, PAGE_HEIGHT * resolution/100); send_config(config); free(config); } int page = 1; FILE *fp = NULL; int sleep_time = 0; while(1) { unsigned char buf[0x1000]; int num_bytes = bulk_read(4, buf, 0x1000); if(num_bytes) sleep_time = 0; if(num_bytes > 2) { if(!fp) { char fname[8]; snprintf(fname, 8, "%03d.raw", page); fprintf(stderr, "Opening '%s'...\n", fname); fp = fopen(fname, "wb"); } fwrite(buf, 1, num_bytes, fp); } else if(num_bytes == 0 && sleep_time < 10) { #ifdef DEBUG fprintf(stderr, "Sleeping\n"); #endif sleep_time++; usleep(200 * 1000); } else if(num_bytes == 2 && buf[0] == 0xc2 && buf[1] == 0x00) { fprintf(stderr, "ERROR: Nothing to scan\n"); break; } else if(num_bytes == 2 && buf[0] == 0xc3 && buf[1] == 0x00) { fprintf(stderr, "ERROR: Paper jam\n"); break; } else if(num_bytes == 1 && buf[0] == 0x80) { fprintf(stderr, "No more pages\n"); break; } else if((num_bytes == 1 && buf[0] == 0x81) || sleep_time >= 10) { fprintf(stderr, "Feeding in another page"); if(sleep_time >= 10) fprintf(stderr, " (timeout)"); fprintf(stderr, "\n"); fclose(fp); fp = NULL; send_config(""); page++; sleep_time = 0; } else if(num_bytes == 1 && buf[0] == 0xc3) { fprintf(stderr, "Paper jam\n"); break; } else if(num_bytes == 1 && buf[0] == 0xc4) { fprintf(stderr, "Scan aborted\n"); break; } else { fprintf(stderr, "Received unknown data: %02x", buf[0]); if(num_bytes == 2) fprintf(stderr, " %02x", buf[1]); fprintf(stderr, "\n"); break; } } if(fp) fclose(fp); control_in_vendor_device(2, 2, 0, 255); /* returns 05 10 02 02 00 */ libusb_release_interface(device_handle, 0); libusb_close(device_handle); libusb_exit(context); return 0; }
int main() { int fd, ret; fd = config_spi(); if (fd < 1) { printf("Failed to configure spi\n"); return fd; } //write_word(fd, 0x00010014, 0xffffffff); int i=0, err_cnt=0; unsigned int *val, *wr_buf, *rd_buf; unsigned int readval; ret = write_word(fd, 0x00017108, 16); printf("write response was %u\n", ret); ret = read_word(fd, 0x00017108, &readval); printf("read response was %u\n", ret); printf("read val was %u\n", readval); int ntrials=1024; val = malloc(sizeof(unsigned int)); for (i=0; i<ntrials; i++) { ret = write_word(fd, 0x00010004+4*i, i); if (ret != 143) { printf("write response was %u\n", ret); } ret = read_word(fd, 0x00010004+4*i, val); if (ret != 143) { printf("read response was %u\n", ret); } if (*val != i) { printf("Read does not match write! (r:%u vs w:%u)\n", *val, i); err_cnt++; } } printf("Errors after %d single writes: %d\n", i, err_cnt); free(val); printf("Trying bulk read of %d words\n", ntrials); wr_buf = calloc(ntrials, sizeof(unsigned int)); rd_buf = calloc(ntrials, sizeof(unsigned int)); for(i=0; i<ntrials; i++) { *(wr_buf+i) = i; } ret = bulk_write(fd, 0x00010004, 4*ntrials, wr_buf); printf("bulk write response was %u\n", ret); ret = bulk_read(fd, 0x00010004, 4*ntrials, rd_buf); for(i=0; i<ntrials; i++) { printf("Wrote %u, got back %u\n", *(wr_buf+i), *(rd_buf+i)); } printf("bulk read response was %u\n", ret); free(wr_buf); free(rd_buf); close(fd); return 0; }