#include "rpmsg_socket.h"
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int RPMSGSOCKET_Create(rpmsg_socket *self,int procId, int endpt, int channelType,sock_rpmsg_t *ptr)
{
socklen_t len;
int err;
fd_set rfds;
(void)(self);
if(NULL == ptr) return -1;
ptr->sock = socket(AF_RPMSG, SOCK_SEQPACKET, 0);
if (ptr->sock < 0)
{
printf("socket failed for send_sock: %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(&ptr->addr_rpmsg, 0, sizeof(struct sockaddr_rpmsg));
ptr->addr_rpmsg.family = AF_RPMSG;
ptr->addr_rpmsg.vproc_id = procId;
ptr->addr_rpmsg.addr = endpt;
if(channelType == 0)
{
printf("Connecting to address %d on vprocId %d\n", ptr->addr_rpmsg.addr, ptr->addr_rpmsg.vproc_id);
len = sizeof(struct sockaddr_rpmsg);
err = connect(ptr->sock, (struct sockaddr *)&ptr->addr_rpmsg, len);
if (err < 0)
{
printf("connect failed: %s (%d)\n", strerror(errno), errno);
return -1;
}
}
else if(channelType == 1)
{
printf("Binding to address %d on vprodId %d\n", ptr->addr_rpmsg.addr, ptr->addr_rpmsg.vproc_id);
len = sizeof(struct sockaddr_rpmsg);
err = bind(ptr->sock, (struct sockaddr *)&ptr->addr_rpmsg, len);
if (err < 0)
{
printf("bind failed: %s (%d)\n", strerror(errno), errno);
return -1;
}
FD_ZERO(&rfds);
FD_SET(ptr->sock, &rfds);
}
else
{
printf("rpmsg create error!!!\n");
return -1;
}
err = getsockname(ptr->sock, (struct sockaddr *)&ptr->addr_rpmsg, &len);
if (err < 0)
{
printf("getsockname failed for send_sock: %s (%d)\n", strerror(errno), errno);
return -1;
}
printf("Our address: socket family: %d, proc id = %d, addr = %d\n",
ptr->addr_rpmsg.family, ptr->addr_rpmsg.vproc_id, ptr->addr_rpmsg.addr);
return 0;
}
int RPMSGSOCKET_Send(rpmsg_socket *self ,int sock, void *buff, int len)
{
int err;
(void)(self);
if(NULL == buff) return -1;
err = send(sock, buff, len, 0);
if (err < 0)
{
printf("sendto failed: %s (%d)\n", strerror(errno), errno);
return -1;
}
return 0;
}
int RPMSGSOCKET_Receive(rpmsg_socket *self, sock_rpmsg_t *ptr, void *buff, int size)
{
socklen_t len;
int ret;
(void)(self);
if (NULL == ptr) return -1;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(ptr->sock, &rfds);
ret = select( ptr->sock + 1, &rfds, NULL, NULL, NULL);
if (ret <= 0)
{
printf("Warning: select failed, trying again %s\n",strerror(errno));
return -1;
}
memset(&ptr->addr_rpmsg, 0, sizeof(ptr->addr_rpmsg));
len = sizeof(ptr->addr_rpmsg);
ret = recvfrom(ptr->sock, buff, size, 0, (struct sockaddr *)&ptr->addr_rpmsg, &len);
if (ret < 0)
{
printf("recvfrom failed: %s (%d)\n", strerror(errno), errno);
return -1;
}
if (len != sizeof(ptr->addr_rpmsg))
{
printf("recvfrom: got bad addr len (%d)\n", len);
return -1;
}
return ret;
}
int RPMSGSOCKET_Close(rpmsg_socket *self)
{
close(self->rpmsgSend.sock);
close(self->rpmsgReceive.sock);
return 0;
}
int gcreate(rpmsg_socket *self,int procId, int endpt, int channelType,sock_rpmsg_t *ptr)
{
return (*self->table->pcreate)(self, procId, endpt, channelType, ptr);
}
int gsend(rpmsg_socket *self, int sock, void *buff, int len)
{
return (*self->table->psend)(self, sock, buff, len);
}
int greceive(rpmsg_socket *self, sock_rpmsg_t *ptr, void *buff, int size)
{
return (*self->table->preceive)(self, ptr, buff, size);
}
int gclose(rpmsg_socket *self)
{
return (*self->table->pclose)(self);
}
void RPMSGSOCKET_constructor(rpmsg_socket *self)
{
if (NULL != self->table) {
printf("rpmsg socket table is not null.\n");
return;
}
static rpmsg_socket_fun_table table =
{
&RPMSGSOCKET_Create,
&RPMSGSOCKET_Send,
&RPMSGSOCKET_Receive,
&RPMSGSOCKET_Close,
};
self->table = &table;
}
void RPMSGSOCKET_destructor(rpmsg_socket *self)
{
if(self != NULL)
{
if(self->table != NULL)
{
self->table = NULL;
}
self = NULL;
}
}