You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
4.4 KiB
175 lines
4.4 KiB
/*
|
|
* socket_ipc.c
|
|
*
|
|
* Created on: 03.11.2014
|
|
* Author: powertomato
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include "DAP_config.h"
|
|
#include "DAP.h"
|
|
#include <arpa/inet.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <netinet/in.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
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, newsockfd, portno, clilen;
|
|
sockaddr_in_t serv_addr;
|
|
sockaddr_in_t cli_addr;
|
|
|
|
// USB HID Callback: when system initializes
|
|
void wait_for_client(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");
|
|
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 binding");
|
|
exit(1);
|
|
}
|
|
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
|
|
DEBUG("ERROR on binding");
|
|
exit(1);
|
|
}
|
|
listen(sockfd,5);
|
|
|
|
clilen = sizeof(cli_addr);
|
|
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
|
|
if (newsockfd < 0){
|
|
DEBUG("ERROR on accept");
|
|
exit(1);
|
|
}
|
|
|
|
int flags;
|
|
flags = fcntl(newsockfd, F_GETFL, 0);
|
|
if(flags < 0 ){
|
|
flags = 0;
|
|
}
|
|
if( fcntl(newsockfd, F_SETFL, flags | O_NONBLOCK) < 0 ){
|
|
DEBUG("ERROR seting non-blocking!\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(newsockfd,response_buff[response_tail],DAP_PACKET_SIZE);
|
|
if (n != DAP_PACKET_SIZE){
|
|
DEBUG("ERROR writing to 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;
|
|
n = read(newsockfd,buff+buff_pos,DAP_PACKET_SIZE);
|
|
|
|
if( n>0 ) {
|
|
buff_pos += n;
|
|
if( buff_pos==DAP_PACKET_SIZE ) {
|
|
buffer_request(buff,DAP_PACKET_SIZE);
|
|
buff_pos=0;
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
|
|
// add a response
|
|
response_head = (response_head + 1) % DAP_PACKET_COUNT;
|
|
if (response_head == response_tail) {
|
|
response_full = 1;
|
|
}
|
|
write_response();
|
|
}
|
|
}
|
|
|
|
|