/* * socket_ipc.c * * Created on: 03.11.2014 * Author: powertomato */ #include #include #include "DAP_config.h" #include "DAP.h" #include #include #include #include #include #include #include #include #include static volatile uint8_t request_full; // Request Buffer Usage Flag static volatile uint32_t request_head; // ReqBuff Buffer In Index static volatile uint32_t request_tail; // ReqBuff Buffer Out Index static volatile uint8_t response_full; // Response Buffer Usage Flag static volatile uint32_t response_head; // Response Buffer In Index static volatile uint32_t response_tail; // Response Buffer Out Index static uint8_t request_buff[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // ReqBuff Buffer static uint8_t response_buff[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer #ifdef __CYGWIN__ /*include oddness...*/ typedef struct { sa_family_t sin_family; /* Address family */ in_port_t sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ /* Pad to size of `struct sockaddr'. */ unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)]; } sockaddr_in_t; #else typedef struct sockaddr_in sockaddr_in_t; #endif int sockfd, csockfd, portno, clilen; sockaddr_in_t serv_addr; sockaddr_in_t cli_addr; void init_socket(void) { request_full = 0; request_head = 0; request_tail = 0; response_full = 0; response_head = 0; response_tail = 0; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { DEBUG("ERROR opening socket: %s\n", strerror(errno)); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); portno = 4777; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); int yes = 1; if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0){ DEBUG("ERROR on setting socket option: %s\n", strerror(errno)); exit(1); } if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ DEBUG("ERROR on binding: %s\n", strerror(errno)); exit(1); } listen(sockfd,5); csockfd = -1; } void close_socket() { if( csockfd == -1){ return; } printf("Closed session!\n"); close(csockfd); csockfd = -1; } static int should_close=0; void late_close_socket() { should_close = 1; } // USB HID Callback: when system initializes void wait_for_client(void) { printf("Wait client... "); clilen = sizeof(cli_addr); csockfd = accept(sockfd, (struct sockaddr*)&cli_addr, (socklen_t*)&clilen); if (csockfd < 0){ DEBUG("ERROR on accept: %s\n", strerror(errno)); exit(1); } int flags; flags = fcntl(csockfd, F_GETFL, 0); if(flags < 0 ){ flags = 0; } if( fcntl(csockfd, F_SETFL, flags | O_NONBLOCK) < 0 ){ DEBUG("ERROR seting non-blocking: %s\n", strerror(errno)); } printf("connected\n"); } // USB HID Callback: when data needs to be prepared for the host int write_response() { if ((response_tail != response_head) || response_full) { int n = write(csockfd,response_buff[response_tail],DAP_PACKET_SIZE); if (n != DAP_PACKET_SIZE){ DEBUG("ERROR writing to socket: %s\n", strerror(errno)); close_socket(); } // remove a response response_tail = (response_tail+1) % DAP_PACKET_COUNT; response_full = 0; return (DAP_PACKET_SIZE); } return (0); } // USB HID Callback: when data is received from the host void buffer_request(uint8_t *buff, int len) { if (len == 0){ return; } if (buff[0] == ID_DAP_TransferAbort) { DAP_TransferAbort = 1; return; } if (request_full) { return; // Discard packet when buffer is full } // add a request memcpy(request_buff[request_head], buff, len); request_head++; if (request_head == DAP_PACKET_COUNT) { request_head = 0; } if (request_head == request_tail) { request_full = 1; } } // Process USB HID Data void process_data(void) { static uint8_t buff[DAP_PACKET_SIZE]; static int buff_pos = 0; int n; if( csockfd == -1 ){ wait_for_client(); } n = read(csockfd,buff+buff_pos,DAP_PACKET_SIZE); if ( n==0 ) { }else if( n>0 ) { buff_pos += n; if( buff_pos==DAP_PACKET_SIZE ) { buffer_request(buff,DAP_PACKET_SIZE); buff_pos=0; } }else if( n<0 ){ switch( errno ) { case EAGAIN: break; default: DEBUG("A problem occured: %d %d %s\n", n, errno,strerror(errno) ); DEBUG("Closing connection!\n"); close_socket(csockfd); break; } } // Process pending requests if ((request_tail != request_head) || request_full) { // Process DAP Command and prepare response DAP_ProcessCommand(request_buff[request_tail], response_buff[response_head]); if( out_state_buff_pos != 0 ){ FTDI_WRITE_OUT(); } // remove a request request_tail = (request_tail + 1) % DAP_PACKET_COUNT; request_full = 0; if( csockfd != -1 ) { // add a response response_head = (response_head + 1) % DAP_PACKET_COUNT; if (response_head == response_tail) { response_full = 1; } write_response(); } } if(should_close) { close_socket(); } should_close = 0; }