Skip to content

Commit

Permalink
Merge pull request #1 from manish1-garg/csi_changes
Browse files Browse the repository at this point in the history
framework/src/csifw: UDP server support to send CSI data to UDP client
  • Loading branch information
sahil1dotgupta authored Sep 16, 2024
2 parents 98b1d78 + d6f39fb commit 6db8ae7
Show file tree
Hide file tree
Showing 7 changed files with 448 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/configs/rtl8730e/loadable_ext_psram/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,7 @@ CONFIG_EXAMPLE_LCD_FPS_TEST=5000
# CONFIG_EXAMPLES_WIFIMANAGER_TEST is not set
# CONFIG_WIFIMANAGER_TEST_TRIAL=5
# CONFIG_EXAMPLES_WIFIMANAGER_AP_LIST_ITEMS_COUNT=10
# CONFIG_CSI_DATA_DUMP_OVER_NETWORK is not set

#
# Platform-specific Support
Expand Down
209 changes: 209 additions & 0 deletions framework/src/csifw/CSILogsDumper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#include "include/CSILogsDumper.h"
#include <sys/socket.h>
#include <netdb.h>
#include <pthread.h>
#include <errno.h>

#define PORT 5000
#define CONTROL_COMMAND_BUFFER_SIZE 128
#define CSI_DATA_DUMP_BUFFER_SIZE 1024

unsigned char gCSIDataDumpBuffer[CSI_DATA_DUMP_BUFFER_SIZE];
char gControlCommandBuffer[CONTROL_COMMAND_BUFFER_SIZE];

csiDataDumpListener gListener = NULL;
static pthread_t gThreadId = -1;
static int gSockFd = -1, gFifoFd = -1;
struct sockaddr_in gServerAddr, gClientAddr;
socklen_t gClientLen = sizeof(gClientAddr);
fd_set readfds;
int maxfd;

static int gWaitingForData = 0;
static int gRemainingBytes = 0;
static int gBytesReadSofar = 0;

static int recv_message(int fd, void *buf, int buflen)
{
int received = 0;
while (1) {
int res = read(fd, buf + received, buflen - received);
if (res < 0) {
int err_no = errno;
if (err_no == EAGAIN || err_no == EINTR) {
continue;
}
CSIFW_LOGE("read error %d\n", err_no);
return -1;
}
received += res;
if (received == buflen) {
break;
}
}
return received;
}

static int print_log(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
return 1;
}

static void print_buf(const unsigned char* buf, int len)
{
print_log("\n RAW DATA %d\n\n", len);
unsigned long long *buff_tmp = (u64 *)buf;
int buff_len = (len/8) + 1;
for (int i = 0; i < buff_len; i++)
print_log("[%02d]0x%016llx\n", i, buff_tmp[i]);
}

void set_event_listener(csiDataDumpListener listener)
{
gListener = listener;
}

void *dataTransmitter(void *arg)
{
int len;
while (1) {
FD_ZERO(&readfds);
FD_SET(gSockFd, &readfds);
FD_SET(gFifoFd, &readfds);
maxfd = (gSockFd > gFifoFd) ? gSockFd : gFifoFd;

CSIFW_LOGI("Wait for an activity on one of the file descriptors");
int ret = select(maxfd + 1, &readfds, NULL, NULL, NULL);
if (ret < 0) {
if (errno == EBADF){
CSIFW_LOGE("select operation failed due to file descripter close: %d", errno);
return;
}
else if(errno == EINTR){
CSIFW_LOGE("select operation failed due to Temporary Interrupt: %d", errno);
continue;;
}
CSIFW_LOGE("select operation failed over file descripters: %d", errno);
return;
}

// Check if there's data on the UDP socket
if (FD_ISSET(gSockFd, &readfds)) {
CSIFW_LOGI("Received an activity on sockfd descriptors");
len = recvfrom(gSockFd, gControlCommandBuffer, CONTROL_COMMAND_BUFFER_SIZE-1, 0, (struct sockaddr *)&gClientAddr, &gClientLen);
if (len < 0) {
continue;
}
gControlCommandBuffer[len] = '\0';
if (strncmp(gControlCommandBuffer, "START", 6) == 0) {
gListener(START_DUMP);
CSIFW_LOGI("Received START command. Starting to send data to client from FIFO");
} else if (strncmp(gControlCommandBuffer, "STOP", 5) == 0) {
gListener(STOP_DUMP);
CSIFW_LOGI("Received STOP command. Stopping data transfer to client from FIFO");
} else {
CSIFW_LOGI("Received unknown command: %s", gControlCommandBuffer);
continue;
}
}

// Check if there's data on the FIFO
if (FD_ISSET(gFifoFd, &readfds)) {
CSIFW_LOGI("Received an activity on Fifo descriptors");

if (!gWaitingForData) {
// Get the length from the first 2 bytes
len = recv_message(gFifoFd, (void *)gCSIDataDumpBuffer, 2);
if (len <= 0) {
CSIFW_LOGE("operation to read length of data from FIFO Failed");
continue;
}
uint16_t length;
memcpy(&length , gCSIDataDumpBuffer, sizeof(length));
CSIFW_LOGI("Read %d length to client:", length);
gRemainingBytes = length;
gWaitingForData = 1;
gBytesReadSofar = 0;
}
if (gWaitingForData) {
// We are expecting to read the actual data
ssize_t bytes_read = read(gFifoFd, gCSIDataDumpBuffer + gBytesReadSofar, gRemainingBytes);
if (bytes_read < 0) {
int err_no = errno;
if (err_no == EAGAIN || err_no == EINTR) {
continue;
}
CSIFW_LOGE("read error %d\n", err_no);
continue; // or return
}

gBytesReadSofar += bytes_read;
gRemainingBytes -= bytes_read;

if (gRemainingBytes == 0) {
// Complete data received
gWaitingForData = 0;
// Send the data to the client
len = sendto(gSockFd, gCSIDataDumpBuffer, gBytesReadSofar, 0, (struct sockaddr *)&gClientAddr, sizeof(gClientAddr));
if (len == -1) {
CSIFW_LOGE("sendto error:%d", errno);
continue;
}
CSIFW_LOGI("Sent %d bytes to client", len);
print_buf(gCSIDataDumpBuffer,len);
}
}
}
}
}

CSIFW_RES csi_logs_dumper_init()
{
if ((gSockFd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
CSIFW_LOGE("failed to create a socket fd");
return CSIFW_ERROR;
}

memset(&gServerAddr, 0, sizeof(gServerAddr));
gServerAddr.sin_family = AF_INET;
gServerAddr.sin_addr.s_addr = INADDR_ANY;
gServerAddr.sin_port = htons(PORT);

if (bind(gSockFd, (struct sockaddr*)&gServerAddr, sizeof(gServerAddr)) < 0) {
CSIFW_LOGE("binding socket failed");
close(gSockFd);
return CSIFW_ERROR;
}
printf("server Socket Created\n");
gFifoFd = open(CSI_DUMP_DATA_QUEUE_NAME, O_RDONLY | O_NONBLOCK);
if (gFifoFd < 0) {
CSIFW_LOGE("open CSI_DUMP_DATA_QUEUE fail %d", errno);
close(gSockFd);
return CSIFW_ERROR;
}

if (pthread_create(&gThreadId, NULL, dataTransmitter, NULL) != 0) {
CSIFW_LOGE("Failed to create dataTransmitter thread %d", errno);
close(gSockFd);
close(gFifoFd);
return CSIFW_ERROR;
}

if (pthread_setname_np(gThreadId, "CSI_DataDumpOverNetwork") != 0) {
CSIFW_LOGE("Error in setting dataTransmitter thread name, error_no: %d", errno);
}
CSIFW_LOGI("CSI_DataDumpOverNetwork created");
return CSIFW_OK;
}

CSIFW_RES csi_logs_dumper_deinit()
{
gListener = NULL;
close(gSockFd);
close(gFifoFd);
return CSIFW_OK;
}
92 changes: 92 additions & 0 deletions framework/src/csifw/CSIService.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include "include/CSIParser.h"
#include "include/CSIPacketReceiver.h"
#include "include/CSINetworkMonitor.h"
#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
#include "include/CSILogsDumper.h"
#endif
#include <errno.h>
#include <fcntl.h>

COLLECT_STATE g_service_state = CSI_STATE_UNITIALIZED;
CONNECTION_STATE g_nw_state;
Expand All @@ -15,6 +20,57 @@ upd_parsed_data_listener g_parsed_callback;
static void* g_ptr;
static csi_action_param_t g_csifw_config __attribute__((aligned(64))) = {0,};

#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
#define CSI_DATA_BUFFER_SIZE 1024

unsigned char gCSIDataBuffer[CSI_DATA_BUFFER_SIZE];
int gDataDumpDescriptor;
bool gCSIDataDumpEvent = STOP_DUMP;

static void csi_data_dump_listener(EVENT event) {
CSIFW_LOGD("csi_data_dump_listener called\n");
gCSIDataDumpEvent = event;
return;
}

static int send_message(int fd, void *buf, int buflen)
{
int sent = 0;
while (1) {
int res = write(fd, (void *)buf + sent, buflen - sent);
if (res < 0) {
int err_no = errno;
if (err_no == EAGAIN || err_no == EINTR) {
continue;
}
CSIFW_LOGE("write error %d", err_no);
return -1;
}
sent += res;
if (sent == buflen) {
break;
}
}
return 0;
}

CSIFW_RES csi_logs_dumper_send_to_queue(unsigned char *csi_buf, int len)
{
// Copy the length to the first two bytes and the data to the rest of the output buffer
uint16_t dest_len = (uint16_t)len;
memcpy(gCSIDataBuffer, &dest_len, 2);
memcpy(gCSIDataBuffer + 2, csi_buf, len);

int res = send_message(gDataDumpDescriptor, (void *)gCSIDataBuffer, len + 2);

if (res < 0) {
CSIFW_LOGE("Failed to send message to CSI_DUMP_DATA_QUEUE");
return CSIFW_ERROR;
}
return CSIFW_OK;
}
#endif

static void CSIRawDataListener(CSIFW_RES res, int raw_csi_buff_len, unsigned char *raw_csi_buff, int raw_csi_data_len)
{
//Send raw data to UPD
Expand All @@ -24,6 +80,15 @@ static void CSIRawDataListener(CSIFW_RES res, int raw_csi_buff_len, unsigned cha
}
if (g_raw_callback) {
g_raw_callback(res, raw_csi_buff_len, raw_csi_buff, g_ptr);
#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
if (gCSIDataDumpEvent) {
CSIFW_RES ret = csi_logs_dumper_send_to_queue(raw_csi_buff, raw_csi_buff_len);
if (ret != CSIFW_OK) {
CSIFW_LOGE("Failed to send CSI data to CSI_DUMP_DATA_QUEUE");
}
CSIFW_LOGD("CSI data sent to CSI_DUMP_DATA_QUEUE");
}
#endif
}
}

Expand All @@ -44,6 +109,28 @@ CSIFW_RES csi_manager_init(void)

CSIFW_RES csi_service_init(upd_raw_data_listener raw_callback, upd_parsed_data_listener parsed_callback, unsigned int interval, void* ptr)
{
#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
int result = mkfifo(CSI_DUMP_DATA_QUEUE_NAME, 0666);
if (result < 0 && result != -EEXIST) {
CSIFW_LOGE("create CSI_DUMP_DATA_QUEUE fail %d", errno);
return CSIFW_ERROR;
}
gDataDumpDescriptor = open(CSI_DUMP_DATA_QUEUE_NAME, O_WRONLY | O_NONBLOCK);
if (gDataDumpDescriptor < 0) {
CSIFW_LOGE("open CSI_DUMP_DATA_QUEUE fail %d", errno);
unlink(CSI_DUMP_DATA_QUEUE_NAME);
return CSIFW_ERROR;
}
result = csi_logs_dumper_init();
if (result != CSIFW_OK) {
CSIFW_LOGE("open csi_logs_dumper_init fail");
close(gDataDumpDescriptor);
unlink(CSI_DUMP_DATA_QUEUE_NAME);
return CSIFW_ERROR;
}
set_event_listener(csi_data_dump_listener);
#endif

g_ptr = ptr;
if (g_service_state != CSI_STATE_UNITIALIZED) {
CSIFW_LOGE("Already Initialized");
Expand Down Expand Up @@ -128,6 +215,11 @@ CSIFW_RES csi_service_deinit()
}
g_service_state = CSI_STATE_UNITIALIZED;
csi_packet_receiver_deinit();
#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
csi_logs_dumper_deinit();
close(gDataDumpDescriptor);
unlink(CSI_DUMP_DATA_QUEUE_NAME);
#endif
if (g_parsed_buffptr) {
free(g_parsed_buffptr);
g_parsed_buffptr = NULL;
Expand Down
3 changes: 3 additions & 0 deletions framework/src/csifw/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ ifeq ($(CONFIG_CSIFW), y)
CFLAGS += -I${TOPDIR}/os/include
CSRCS += CSIPacketReceiver.c CSIParser.c CSIService.c PingGenerator.c CSINetworkMonitor.c rb.c

ifeq ($(CONFIG_CSI_DATA_DUMP_OVER_NETWORK), y)
CSRCS += CSILogsDumper.c
endif

DEPPATH += --dep-path src/csifw
VPATH += :src/csifw
Expand Down
21 changes: 21 additions & 0 deletions framework/src/csifw/include/CSILogsDumper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef __CSI_LOGS_DUMPER__
#define __CSI_LOGS_DUMPER__

#include "csifw.h"

#ifdef CONFIG_CSI_DATA_DUMP_OVER_NETWORK
#define CSI_DUMP_DATA_QUEUE_NAME "/dev/csidump_data"

typedef enum EVENT {
STOP_DUMP,
START_DUMP
} EVENT;

CSIFW_RES csi_logs_dumper_init();
CSIFW_RES csi_logs_dumper_deinit();

typedef void (*csiDataDumpListener)(EVENT event);
void set_event_listener(csiDataDumpListener listener);
#endif

#endif /* __CSI_LOGS_DUMPER__ */
16 changes: 16 additions & 0 deletions tools/csi_datadump/README_csi_datadump_udp_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# How To Run csi_datadump_udp_client.c File

## Steps:
### 1. First compile the file:
```bash
gcc -o program csi_datadump_udp_client.c -lpthread
```

### 2. Run the program
Command Format: ./program <IP_ADDRESS> <PORT>
```bash
./program 192.168.1.120 5000
```

## How to STOP the datadump
#### Type *STOP* in terminal and press enter.
Loading

0 comments on commit 6db8ae7

Please sign in to comment.