Commit 17153d0b authored by Alessandro Rubini's avatar Alessandro Rubini

use mini-rpc instead of wripc

parent 61536e33
......@@ -13,8 +13,7 @@ WR_INSTALL_ROOT ?= $(WRS_OUTPUT_DIR)/images/wr
WRDEV_DIR ?= $(WRS_BASE_DIR)/..
# subdirectories we want to compile
SUBDIRS = mini-rpc
SUBDIRS += libswitchhw libwripc libptpnetif
SUBDIRS = mini-rpc libswitchhw libptpnetif
SUBDIRS += wrsw_hal wrsw_rtud spll_dbg_proxy
SUBDIRS += wr_mon rtu_stat #test_rtu
......
......@@ -27,7 +27,32 @@ typedef struct{
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_MAN_ADJUST_PHASE 2
void ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
void ptpdexp_cmd(int cmd, int value);
extern int ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
extern int ptpdexp_cmd(int cmd, int value);
/* Export structures, shared by server and client for argument matching */
#ifdef PTP_EXPORT_STRUCTURES
//int ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
struct minipc_pd __rpcdef_get_sync_state = {
.name = "get_sync_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, ptpdexp_sync_state_t),
.args = {
MINIPC_ARG_END,
},
};
//int ptpdexp_cmd(int cmd, int value);
struct minipc_pd __rpcdef_cmd = {
.name = "cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
#endif /* PTP_EXPORT_STRUCTURES */
#endif
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CFLAGS = -I. -O2 -I../include -I../wrsw_hal -I../libwripc -DDEBUG
CFLAGS = -I. -O2 -I../include -I../wrsw_hal -I../mini-rpc -DDEBUG
OBJS = hal_client.o netif_test.o ptpd_netif.o
......
#include <stdio.h>
#include <stdlib.h>
#include <minipc.h>
#define HAL_EXPORT_STRUCTURES
#include "hal_exports.h"
#include <wr_ipc.h>
#define DEFAULT_TO 200 /* ms */
static wripc_handle_t hal_cli;
static struct minipc_ch *hal_ch;
int halexp_check_running()
{
......@@ -22,34 +25,47 @@ int halexp_reset_port(const char *port_name)
int halexp_calibration_cmd(const char *port_name, int command, int on_off)
{
int rval;
wripc_call(hal_cli, "halexp_calibration_cmd", &rval,3, A_STRING(port_name), A_INT32(command), A_INT32(on_off));
int ret, rval;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_calibration_cmd,
&rval, port_name, command, on_off);
if (ret < 0)
return ret;
return rval;
}
int halexp_lock_cmd(const char *port_name, int command, int priority)
{
int rval;
wripc_call(hal_cli, "halexp_lock_cmd", &rval, 3, A_STRING(port_name), A_INT32(command), A_INT32(priority));
int ret, rval;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_lock_cmd,
&rval, port_name, command, priority);
if (ret < 0)
return ret;
return rval;
}
int halexp_query_ports(hexp_port_list_t *list)
{
wripc_call(hal_cli, "halexp_query_ports", list, 0);
return 0;
int ret;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_query_ports,
list /* return val */);
return ret;
}
int halexp_get_port_state(hexp_port_state_t *state, const char *port_name)
{
wripc_call(hal_cli, "halexp_get_port_state", state, 1, A_STRING(port_name));
return 0;
int ret;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_query_ports,
state /* retval */, port_name);
return ret;
}
int halexp_pps_cmd(int cmd, hexp_pps_params_t *params)
{
int rval;
wripc_call(hal_cli, "halexp_pps_cmd", &rval, 2, A_INT32(cmd), A_STRUCT(*params));
int ret, rval;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_pps_cmd,
&rval, cmd, params);
if (ret < 0)
return ret;
return rval;
}
......@@ -57,7 +73,7 @@ int halexp_pps_cmd(int cmd, hexp_pps_params_t *params)
int halexp_pll_cmd(int cmd, hexp_pll_cmd_t *params)
{
int rval;
wripc_call(hal_cli, "halexp_pll_cmd", &rval, 2, A_INT32(cmd), A_STRUCT(*params));
wripc_call(hal_ch, "halexp_pll_cmd", &rval, 2, A_INT32(cmd), A_STRUCT(*params));
return rval;
}
......@@ -65,9 +81,18 @@ int halexp_pll_cmd(int cmd, hexp_pll_cmd_t *params)
int halexp_client_init()
{
hal_cli = wripc_connect(WRSW_HAL_SERVER_ADDR);
if(hal_cli < 0)
hal_ch = minipc_client_create(WRSW_HAL_SERVER_ADDR, 0);
if (!hal_ch)
return -1;
else
return 0;
}
int halexp_extsrc_cmd(int command)
{
int ret, rval;
ret = minipc_call(hal_ch, DEFAULT_TO, &__rpcdef_extsrc_cmd,
&rval, command);
return rval;
}
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
CFLAGS = -I. -O2 -I../include
OBJS = helper_arm.o wr_ipc.o
LIB = libwripc.a
all: $(LIB)
$(LIB): $(OBJS)
$(AR) rc $@ $^
install: all
install -d $(WR_INSTALL_ROOT)/lib
install $(LIB) $(WR_INSTALL_ROOT)/lib
clean:
rm -f $(LIB) $(OBJS)
// architecture-specific _do_call() functions
#ifdef __i386__
static int _do_call(void *func_ptr, void *args, int args_size)
{
int rval;
asm volatile (
"movl %%esp, %%edi\n"
"movl %%ebx, %%ecx\n"
"subl %%ebx, %%edi\n"
"shrl $2, %%ecx\n"
"cld\n"
"rep\n"
"movsl\n"
"subl %3, %%esp\n"
"call *%%eax\n"
"addl %3, %%esp\n"
: "=a"(rval)
: "a"(func_ptr), "S"(args), "b"(args_size)
:
);
/* "si", "di", "ax", "bx", "cx", "memory" */
return rval;
}
#endif
#ifdef __arm__
extern int _do_call(void *func_ptr, void *args, int args_size);
#endif
.global _do_call
_do_call:
stmfd sp!, {r4, r5, r6, r7, fp, lr}
mov r4, r1 // r4 = args_buffer
mov lr, r0 // lr = func_ptr
mov r5, r2 // r5 = args_size
ldr r0, [r4, #0]
ldr r1, [r4, #4]
ldr r2, [r4, #8]
ldr r3, [r4, #12]
mov fp, sp
sub r5, #16
cmp r5, #0
blt do_call
add r4, #16
mov r7, sp
sub r7, r5
sub sp, r5
copy_args:
ldr r6, [r4]
str r6, [r7]
add r7, #4
add r4, #4
sub r5, #4
cmp r5, #0
bne copy_args
do_call:
mov r6, lr
mov lr, pc
bx r6
mov sp, fp
ldmfd sp!, {r4, r5, r6, r7, fp, lr}
bx lr
struct test_struct {
int apples;
int peas;
char name[80];
float value;
};
struct state_struct {
char state_name[80];
float t;
int x;
};
void test_void(double *ptr, double a, double b)
{
*ptr = a+b;
}
main()
{
test_void(1000, 1.123, 2.245);
}
\ No newline at end of file
#include <stdio.h>
#include "wr_ipc.h"
#include "structs.h"
main()
{
wripc_handle_t cli;
int res_int;
float result, a,b;
struct state_struct s;
cli = wripc_connect("test");
wripc_call(cli, "bigfunc", &res_int, 8, A_INT32(1), A_INT32(2), A_INT32(3), A_INT32(4), A_INT32(5), A_INT32(6), A_INT32(7), A_INT32(8));
printf("1+...+8 = %d\n", res_int);
a=2.2; b= 4.4;
wripc_call(cli, "add", &result, 2, A_FLOAT(a), A_FLOAT(b));
printf("%.1f + %.1f = %.1f\n", a,b,result);
wripc_call(cli, "get_state", &s, 1, A_INT32(12345));
printf("state->name %s\n", s.state_name);
printf("state->t %.3f\n", s.t);
printf("state->x %d\n", s.x);
struct test_struct s2;
s2.apples = 10;
s2.peas = 15;
strcpy(s2.name, "Javier");
s2.value = 17.50;
// wripc_call(cli, "structure_test", &result, 1, A_STRUCT(s2));
wripc_call(cli, "string_test", &res_int, 3, A_STRING("Hello, world"), A_INT32(1), A_INT32(100));
printf("rval = %d\n", res_int);
usleep(1000);
wripc_close(cli);
}
float ret_float() { return 1.0; }
double ret_double() { return 1.0; }
void test_float(double a)
{
*(volatile double *) 0xdeadbee0 = a;
}
main()
{
float x = 123.345;
test_float(x);
}
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include "wr_ipc.h"
#include "structs.h"
int bigfunc(int a, int b, int c, int d, int e, int f, int g, int h)
{
printf("Call bigfunc: %d %d %d %d %d %d %d %d\n" ,a,b,c,d,e,f,g,h);
return a+b+c+d+e+f+g+h;
}
void add(float *rval, float a, float b)
{
printf("Call add: %.3f + %.3f\n", a,b);
*rval = a + b;
}
int string_test(char *string, int a, int b)
{
printf("Call string_test: a = %d, b= %d, string = '%s'\n", a,b,string);
return 12345;
}
void structure_test(struct test_struct *s)
{
printf("Call structure_test: %s got %d apples and %d peas of total value %.3f\n",s->name, s->apples, s->peas, s->value);
}
void get_state(struct state_struct *rval, int request)
{
printf("Call get_state: request = %d\n", request);
rval->t = 123.0;
strcpy(rval->state_name, "SomeState");
rval->x = request;
}
int main()
{
wripc_handle_t srv;
srv = wripc_create_server("test");
// add(10000, 1.0, 2.0);
wripc_export(srv, T_INT32, "bigfunc", bigfunc, 8, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32 );
wripc_export(srv, T_FLOAT, "add", add, 2, T_FLOAT, T_FLOAT);
wripc_export(srv, T_INT32, "sub", add, 2, T_INT32, T_INT32);
wripc_export(srv, T_INT32, "string_test", string_test, 3, T_STRING, T_INT32, T_INT32);
wripc_export(srv, T_VOID, "structure_test", structure_test, 1, T_STRUCT(struct test_struct));
wripc_export(srv, T_STRUCT(struct state_struct), "get_state", get_state, 1, T_INT32);
for(;;) wripc_process(srv);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#include <poll.h>
//#include <inttypes.h> -- now in ptpd-wrappers.h
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <wr_ipc.h>
#include "asm_helpers.h"
#ifdef DEBUG
#define DBG(...) dbg_printf(__func__, __VA_ARGS__)
#else
#define DBG(...)
#endif
#define WRIPC_SERVER 1
#define WRIPC_CLIENT 2
#define WRIPC_MAX_FUNCS 128
#define WRIPC_MAX_ARGS 16
#define WRIPC_MAX_HANDLES 16
#define WRIPC_MAX_EVENTS 128
#define WRIPC_MAX_CONNECTIONS 16
#define MSG_TYPE_CALL 1
#define MSG_TYPE_EVENT_SUBSCRIBE 2
#define MSG_TYPE_EVENT_NOTIFY 3
#define MSG_TYPE_ERROR 4
#define MSG_TYPE_CALL_ACK 5
#define MSG_TYPE_SUBSCRIBE_ACK 6
#define MAX_MESSAGE_SIZE 2048
#define REPLY_TIMEOUT 20000 // msec
#define ARG_TYPE_MASK 0xff
struct wripc_function {
int in_use;
char *name;
void *ptr;
int n_args;
int arg_types[WRIPC_MAX_ARGS];
int rval_type;
int rval_size;
};
struct wripc_connection {
int in_use;
int cli_fd;
uint32_t event_mask[WRIPC_MAX_EVENTS / 32];
};
struct wripc_event {
int in_use;
char *name;
uint32_t id;
};
struct wripc_server_context {
int fd;
char *name;
int num_functions;
struct wripc_function *funcs;
struct wripc_event *events;
struct wripc_connection *conns;
int current_event_id;
// int num_events;
//struct wripc_event *evts;
};
struct wripc_client_context {
int fd;
char *srv_name;
};
struct handle_struct {
int in_use;
int type;
struct wripc_server_context *srv;
struct wripc_client_context *cli;
};
static struct handle_struct handle_map[WRIPC_MAX_HANDLES];
/*********************
Common Functions
*********************/
#ifdef DEBUG
static void dbg_printf(const char *func, const char *fmt, ...)
{
va_list ap;
fprintf(stderr,"%s: ", func);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
#endif
static struct wripc_server_context *get_srv_context(wripc_handle_t handle)
{
if(handle <0 || handle >= WRIPC_MAX_HANDLES)
return NULL;
if(!handle_map[handle].in_use || handle_map[handle].type !=WRIPC_SERVER)
return NULL;
return handle_map[handle].srv;
}
static struct wripc_client_context *get_cli_context(wripc_handle_t handle)
{
if(handle <0 || handle >= WRIPC_MAX_HANDLES)
return NULL;
if(!handle_map[handle].in_use || handle_map[handle].type !=WRIPC_CLIENT)
return NULL;
return handle_map[handle].cli;
}
static wripc_handle_t alloc_handle(int type)
{
int i;
for(i = 0; i<WRIPC_MAX_HANDLES; i++)
if(!handle_map[i].in_use)
{
handle_map[i].type = type;
handle_map[i].in_use = 1;
return (wripc_handle_t) i;
}
return -1;
}
static void free_handle(wripc_handle_t handle)
{
if(handle >= 0 && handle <= WRIPC_MAX_HANDLES)
handle_map[handle].in_use = 0;
}
static void *safe_zmalloc(size_t howmuch)
{
void *p;
p = malloc(howmuch);
if(!p)
{
DBG("FATAL: not enough memory\n");
exit(-1);
}
memset(p, 0, howmuch);
return p;
}
/*********************
Server-side
*********************/
wripc_handle_t wripc_create_server(const char *name)
{
int fd;
int rval;
struct wripc_server_context *srv;
wripc_handle_t handle;
struct sockaddr_un sun;
fd = socket(SOCK_STREAM, AF_UNIX, 0);
if(fd < 0)
return fd;
sun.sun_family = AF_UNIX;
strncpy(sun.sun_path, "/tmp/.wripc_", sizeof(sun.sun_path));
strncat(sun.sun_path, name, sizeof(sun.sun_path));
unlink(sun.sun_path);
if((rval = bind (fd, (struct sockaddr *)&sun,
sizeof(struct sockaddr_un))) < 0)
{
perror("bind");
close(fd);
return rval;
}
if((rval = listen(fd, WRIPC_MAX_CONNECTIONS)) < 0)
{
close(fd);
return rval;
}
srv = safe_zmalloc(sizeof(struct wripc_server_context));
if(!srv)
{
close(fd);
return -1;
}
handle = alloc_handle(WRIPC_SERVER);
if(handle < 0)
{
close(fd);
free(srv);
return -1;
}
srv->fd = fd;
srv->name = strdup(name);
srv->num_functions = 0;
srv->funcs = safe_zmalloc(WRIPC_MAX_FUNCS
* sizeof(struct wripc_function));
srv->events = safe_zmalloc(WRIPC_MAX_FUNCS
* sizeof(struct wripc_event));
srv->conns = safe_zmalloc(WRIPC_MAX_FUNCS
* sizeof(struct wripc_connection));
handle_map[handle].srv = srv;
fcntl(fd, F_SETFL, O_NONBLOCK);
DBG("created server '%s'\n", name);
return handle;
}
wripc_handle_t wripc_connect(const char *name)
{
int fd;
int rval;
struct wripc_client_context *cli;
wripc_handle_t handle;
struct sockaddr_un sun;
handle = alloc_handle(WRIPC_CLIENT);
if(handle < 0)
return -ENOMEM;
cli = malloc(sizeof(struct wripc_client_context));
if(!cli)
return -ENOMEM;
handle_map[handle].cli = cli;
fd = socket(SOCK_STREAM, AF_UNIX, 0);
if(fd < 0)
return fd;
sun.sun_family = AF_UNIX;
strncpy(sun.sun_path, "/tmp/.wripc_", sizeof(sun.sun_path));
strncat(sun.sun_path, name, sizeof(sun.sun_path));
//unlink(sun.sun_path);
if((rval = connect (fd, (struct sockaddr *)&sun,
sizeof(struct sockaddr_un))) < 0)
{
DBG("connect failed: %s\n", strerror(errno));
close(fd);
return rval;
}
cli->fd = fd;
DBG("fd = %d\n", fd);
return handle;
}
static struct wripc_function *find_function(struct wripc_server_context *srv,
const char *func_name)
{
int i;
for(i=0;i<WRIPC_MAX_FUNCS;i++)
if(srv->funcs[i].in_use && !strcmp(func_name,
srv->funcs[i].name))
return &srv->funcs[i];
return NULL;
}
static struct wripc_function *new_function(struct wripc_server_context *srv,
const char *func_name)
{
int i;
if(find_function(srv, func_name) != NULL) // already registered
return NULL;
for(i=0;i<WRIPC_MAX_FUNCS;i++)
if(!srv->funcs[i].in_use)
return &srv->funcs[i];
return NULL;
}
static int get_arg_size(uint32_t arg_type)
{
switch(arg_type & ARG_TYPE_MASK)
{
case T_FLOAT:
case T_INT32:
case T_INT16:
case T_INT8: return 4;
case T_DOUBLE: return 8;
case T_STRUCT_TYPE: return (arg_type >> 8);
case T_VOID: return 0;
default: return 0;
}
}
int wripc_export(wripc_handle_t handle, int rval_type, const char *name,
void *func_ptr, int num_args, ...)
{
struct wripc_server_context *srv;
struct wripc_function *func;
va_list ap;
int i;
DBG("export '%s'\n", name);
if(num_args > WRIPC_MAX_ARGS)
return -EINVAL;
srv = get_srv_context(handle);
if(!srv) return -EINVAL;
func = new_function(srv, name);
if(!func) return -ENOSPC;
func->name = strdup(name);
func->rval_type = rval_type & ARG_TYPE_MASK;
func->rval_size = get_arg_size(rval_type);
func->ptr = func_ptr;
func->n_args = num_args;
va_start(ap, num_args);
for(i=0; i<num_args; i++)
func->arg_types[i] = va_arg(ap, int);
va_end(ap);
func->in_use = 1;
return 0;
}
static struct wripc_connection *new_connection(struct wripc_server_context *srv)
{
int i;
for(i=0;i<WRIPC_MAX_CONNECTIONS; i++)
if(!srv->conns[i].in_use)
{
srv->conns[i].in_use = 1;
return &srv->conns[i];
}
return NULL;
}
static void reply_error(struct wripc_connection *conn, int err_val)
{
uint32_t buffer[3];
buffer[0] = MSG_TYPE_ERROR;
buffer[1] = 3;
buffer[2] = err_val;
send(conn->cli_fd, buffer, sizeof(buffer), 0);
}
static char *extract_string(uint32_t *ptr)
{
int len = *ptr++;
char * buf = malloc(len + 1);
memcpy(buf, ptr, len);
buf[len] = 0;
return buf;
}
//extern int _do_call(void *func_ptr, void *args, int args_size);
// FIXME: optimize search
static inline struct wripc_function *lookup_function(
struct wripc_server_context *srv, const char *func_name)
{
int i;
for(i=0;i < WRIPC_MAX_FUNCS; i++)
if(srv->funcs[i].in_use)
if(!strcmp(srv->funcs[i].name, func_name))
return &srv->funcs[i];
return NULL;
}
static inline int deserialize_string(uint32_t *stream, int current_pos,
int buf_size, uint32_t *dst)
{
int length = stream[current_pos];
int num_words = ((length + 4) >> 2) + 1;
char *str_p;
// printf("DeserializeString: cp %d nwords %d bsize %d \n",
// current_pos, num_words, buf_size);
if( current_pos + num_words > buf_size)
return -1;
str_p = (char *)(stream + current_pos + 1);
// printf("Str_P %s length %d\n", str_p);
if(str_p[length])
return -1;
//for(i=0;i<num_words;i++) printf("%08x ", stream[current_pos+i]);
//printf("\n");
*dst = (uint32_t)&stream[current_pos + 1];
return current_pos + num_words;
}
static inline int deserialize_struct(uint32_t *stream, int current_pos,
int buf_size, uint32_t *dst)
{
int size = stream[current_pos];
int num_words = ((size + 3) >> 2) + 1;
//printf("bs %d cp %d nw %d\n", buf_size, current_pos, num_words);
if( current_pos + num_words > buf_size)
return -1;
*dst = (uint32_t)&stream[current_pos + 1];
return current_pos + num_words;
}
static inline int serialize_string(uint32_t *buffer, int current_pos,
int max_pos, char *str)
{
int len;
int num_words;
len = strlen(str);
num_words = 1 + ((len + 4) >> 2);
if(current_pos + num_words >= max_pos) return -ENOMEM;
buffer[current_pos] = len;
memcpy(buffer + current_pos + 1, str, len+1);
current_pos += num_words;
return current_pos;
}
static inline int serialize_struct(uint32_t *buffer, int current_pos,
int max_pos, int size, void *ptr)
{
int num_words = 1 + ((size + 3) >> 2);
if(current_pos + num_words >= max_pos)
return -ENOMEM;
buffer[current_pos] = size;
memcpy(buffer + current_pos + 1, ptr, size);
return current_pos + num_words;
}
static inline int send_call_reply(struct wripc_connection *conn,
struct wripc_function *func, uint32_t *rval,
int buf_size)
{
int total_size;
uint32_t buf[MAX_MESSAGE_SIZE];
buf[0] = MSG_TYPE_CALL_ACK;
buf[1] = 0; // size will be put here later
if(func->rval_type == T_VOID)
{
buf[2] = 0;
total_size = 3;
} else {
switch(func->rval_type)
{
case T_INT8:
case T_INT16:
case T_INT32:
case T_FLOAT:
case T_DOUBLE:
buf[2] = func->rval_size;
memcpy(buf + 3, rval, func->rval_size);
total_size = 3 + ((func->rval_size + 3) >> 2);
break;
case T_STRING:
total_size = serialize_string(buf, 2,
MAX_MESSAGE_SIZE,
(char *)rval);
if(total_size < 0) {
reply_error(conn, WRIPC_ERROR_MALFORMED_PACKET);
return 0;
}
case T_STRUCT_TYPE:
//printf("ReturnsStruct: size %d\n", func->rval_size);
total_size = serialize_struct(buf, 2,
MAX_MESSAGE_SIZE,
func->rval_size, rval);
if(total_size < 0) {
reply_error(conn, WRIPC_ERROR_MALFORMED_PACKET);
return 0;
}
break;
}
}
buf[1] = total_size << 2;
DBG("about_to_send ts %d ", total_size * 4);
int n_sent = send(conn->cli_fd, buf, total_size * 4, 0);
DBG("about_to_send ts %d n_sent %d", total_size * 4, n_sent);
if(n_sent != total_size * 4)
return -1;
return 0;
}
static int handle_call(struct wripc_server_context *srv,
struct wripc_connection *conn, uint32_t *buf,
int buf_size)
{
struct wripc_function *func;
char *func_name;
uint32_t arg_buf[WRIPC_MAX_ARGS * 2];
uint32_t rval_buf[MAX_MESSAGE_SIZE];
int arg_buf_pos;
int num_args;
int current_pos;
int i;
int direct_rval;
func_name = extract_string(buf + 3);
func = lookup_function(srv, func_name);
num_args = buf[2];
current_pos = 3 + 1+ ((strlen(func_name)+4)>>2);
DBG("conn %x call %s nargs = %d\n", conn, func_name, num_args);
if(!func)
{
reply_error(conn, WRIPC_ERROR_UNKNOWN_FUNCTION);
return 0;
}
if(func->rval_type == T_INT8
|| func->rval_type == T_INT16
|| func->rval_type == T_INT32
|| func->rval_type == T_VOID)
{
// these functions can return the value directly
// (e.g. int add (a, b) { return a+b; }
direct_rval = 1;
arg_buf_pos = 0;
} else {
direct_rval = 0;
arg_buf_pos = 1;
}
for(i=0;i<num_args;i++)
{
int arg_type = buf[current_pos++];
DBG("argtype %d cp %d\n", arg_type, current_pos);
switch(arg_type)
{
case T_INT8:
arg_buf[arg_buf_pos++] = buf[current_pos++] & 0xff;
break;
case T_INT16:
arg_buf[arg_buf_pos++] = buf[current_pos++] & 0xffff;
break;
case T_INT32:
arg_buf[arg_buf_pos++] = buf[current_pos++]&0xffffffff;
break;
case T_DOUBLE:
{
arg_buf[arg_buf_pos++] = buf[current_pos++];
arg_buf[arg_buf_pos++] = buf[current_pos++];
break;
}
case T_FLOAT:
{
float tmp = (float) (*(double *) &buf[current_pos]);
arg_buf[arg_buf_pos++] = *(uint32_t *)&tmp;
current_pos += 2; break;
}
case T_STRING:
current_pos =
deserialize_string(buf, current_pos,
buf_size,
&arg_buf[arg_buf_pos]);
DBG("DeserializeString, pos = %d string = %s\n",
current_pos, &arg_buf[arg_buf_pos]);
arg_buf_pos++;
if(current_pos < 0)
{
reply_error(conn, WRIPC_ERROR_MALFORMED_PACKET);
return 0;
}
break;
case T_STRUCT_TYPE:
current_pos =
deserialize_struct(buf, current_pos,
buf_size,
&arg_buf[arg_buf_pos++]);
DBG("StructArg, pos= %d\n",current_pos);
if(current_pos < 0)
{
reply_error(conn, WRIPC_ERROR_MALFORMED_PACKET);
return 0;
}
break;
default:
reply_error(conn, WRIPC_ERROR_MALFORMED_PACKET);
}
}
if(!direct_rval)
{
arg_buf[0] = (uint32_t) rval_buf;
DBG("Rval_ptr: %x\n", arg_buf[0]);
DBG("Func_ptr: %x\n", func->ptr);
//DBG("String: %s\n", arg_buf[1]);
_do_call(func->ptr, arg_buf, arg_buf_pos * 4);
} else {
DBG("Rval_ptr: %x\n", arg_buf[0]);
DBG("Func_ptr: %x\n", func->ptr);
rval_buf[0] = _do_call(func->ptr, arg_buf, arg_buf_pos * 4);
DBG("Rval: %d\n", rval_buf[0]);
}
return send_call_reply(conn, func, rval_buf, MAX_MESSAGE_SIZE);
}
static int handle_client_request(struct wripc_server_context *srv,
struct wripc_connection *conn)
{
uint32_t buffer[MAX_MESSAGE_SIZE];
int n_recv;
int rq_type;
int size;
for(;;)
{
n_recv = recv(conn->cli_fd, buffer, sizeof(buffer), 0);
if(!n_recv) return 0;
if(n_recv & 3)
return -1; // non-integer number of words?
rq_type = buffer[0];
size = buffer[1];
if(n_recv != size)
{
reply_error(conn, WRIPC_ERROR_INVALID_REQUEST);
continue;
}
switch(rq_type)
{
case MSG_TYPE_CALL:
return handle_call(srv, conn, buffer, n_recv >> 2);
break;
}
}
return 0;
}
static int process_server(struct wripc_server_context *srv)
{
struct pollfd pfd;
struct sockaddr_un sun;
int new_fd;
int i;
socklen_t slen;
slen = sizeof(struct sockaddr_un);
if((new_fd = accept(srv->fd,(struct sockaddr *) &sun, &slen)) > 0)
{
struct wripc_connection *conn;
fcntl(new_fd, F_SETFL, O_NONBLOCK);
DBG("got connection: fd = %d.\n", new_fd);
conn = new_connection(srv);
if(conn)
conn->cli_fd = new_fd;
else {
DBG("too many connections active, refusing...\n");
close(new_fd);
}
}
for(i=0;i<WRIPC_MAX_CONNECTIONS;i++)
{
struct wripc_connection *conn = &srv->conns[i];
if(conn->in_use)
{
pfd.fd = conn->cli_fd;
pfd.events = POLLIN | POLLHUP | POLLERR ;
pfd.revents = 0;
if(poll(&pfd, 1, 0) > 0)
{
if(pfd.revents & (POLLERR | POLLHUP))
{
DBG("poll returned error, "
"killing connection (fd = %d)\n",
conn->cli_fd);
conn->in_use = 0;
close(conn->cli_fd);
} else if(pfd.revents & POLLIN) {
int rv = handle_client_request(srv,
conn);
DBG("handle request returned %d\n", rv);
if(rv < 0)
{
DBG("Request failed. "
"Closing connection");
conn->in_use = 0;
close(conn->cli_fd);
}
}
}
}
}
return 0;
}
int wripc_process(wripc_handle_t handle)
{
struct wripc_server_context *srv;
srv = get_srv_context(handle);
if(srv) return process_server(srv);
return 0;
}
void wripc_close(wripc_handle_t handle)
{
struct wripc_server_context *srv;
struct wripc_client_context *cli;
int i;
srv = get_srv_context(handle);
cli = get_cli_context(handle);
if(!srv && !cli) return;
if(srv)
{
for(i=0; i<WRIPC_MAX_CONNECTIONS;i++)
if(srv->conns[i].in_use)
close(srv->conns[i].cli_fd);
free(srv->conns);
free(srv->funcs);
free(srv->events);
close(srv->fd);
free(srv);
}
if(cli)
{
close(cli->fd);
free(cli);
}
free_handle(handle);
}
static int recv_with_timeout(int fd, void *buf, size_t len, int timeout)\
{
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN | POLLHUP;
pfd.revents = 0;
if(poll(&pfd, 1, REPLY_TIMEOUT) <= 0)
return WRIPC_ERROR_TIMEOUT;
return recv(fd, buf, len, 0);
}
int wripc_call(wripc_handle_t handle, const char *name, void *rval,
int num_args, ...)
{
uint32_t buffer[MAX_MESSAGE_SIZE];
int current_pos;
int name_len;
int i;
//int arg_types[WRIPC_MAX_ARGS];
int rv, msg_size;
va_list ap;
struct wripc_client_context *cli = get_cli_context(handle);
DBG("call %s handle %d ctx %x\n", name, handle, cli);
if(!cli) return -EINVAL;
if(num_args > WRIPC_MAX_ARGS)
return WRIPC_ERROR_INVALID_ARG;
name_len = strlen(name);
if(name_len > 128)
return WRIPC_ERROR_INVALID_ARG;
//DBG("dupa?");
buffer[0] = MSG_TYPE_CALL;
buffer[1] = 0; // size will be put here later
buffer[2] = num_args;
buffer[3] = name_len;
memcpy(buffer + 4, name, name_len);
current_pos = ((name_len + 4) >> 2) + 4;
va_start(ap, num_args);
for(i = 0; i<num_args; i++)
{
uint32_t varg = va_arg(ap, uint32_t);
int type = varg & ARG_TYPE_MASK;
int struct_size = varg >> 8;
if(current_pos >= MAX_MESSAGE_SIZE)
return WRIPC_ERROR_NO_MEMORY;
buffer[current_pos++] = type;
switch(type)
{
case T_INT8:
buffer[current_pos++] = va_arg(ap, uint32_t) & 0xff;
break;
case T_INT16:
buffer[current_pos++] = va_arg(ap, uint32_t) & 0xffff;
break;
case T_INT32:
buffer[current_pos++] = va_arg(ap, uint32_t);
break;
case T_FLOAT:
case T_DOUBLE: {
double tmp = va_arg(ap, double);
buffer[current_pos++] = *(uint32_t *) (&tmp);
buffer[current_pos++] = *(((uint32_t *) (&tmp)) + 1);
break;
}
case T_STRING: {
// DBG("serialize: T_STRING\n");
int new_pos = serialize_string(buffer, current_pos,
MAX_MESSAGE_SIZE,
va_arg(ap, char *));
if(new_pos < 0) return WRIPC_ERROR_NO_MEMORY;
current_pos = new_pos;
break;
}
case T_STRUCT_TYPE: {
int new_pos;
void *struct_ptr = va_arg(ap, void*);
new_pos = serialize_struct(buffer, current_pos,
MAX_MESSAGE_SIZE,
struct_size, struct_ptr);
if(new_pos < 0) return WRIPC_ERROR_NO_MEMORY;
current_pos = new_pos;
break;
}
default:
DBG("invalid parameter type %d\n", type);
return WRIPC_ERROR_INVALID_ARG;
}
}
//for(i=0; i<current_pos; i++) fprintf(stderr,"%08x ", buffer[i]);
//fprintf(stderr,"\n");
msg_size = current_pos * sizeof(uint32_t);
buffer[1] = msg_size; // store the message size
rv = send(cli->fd, buffer, msg_size, 0);
DBG("total size: %d, sent: %d\n", current_pos*4, rv);
if(rv != msg_size)
return rv;
rv = recv_with_timeout(cli->fd, buffer, 4*MAX_MESSAGE_SIZE,
REPLY_TIMEOUT);
if(rv <= 0 || rv != buffer[1]) return WRIPC_ERROR_MALFORMED_PACKET;
if(buffer[0] == MSG_TYPE_ERROR) // oops. we received an error
return (int) buffer[2];
else if (buffer[0] == MSG_TYPE_CALL_ACK) // ack packet contains retval
{
int rval_size = buffer[2];
if(rval_size)
memcpy(rval, buffer + 3, rval_size);
return 0;
} else return WRIPC_ERROR_MALFORMED_PACKET;
return 0;
};
static int do_subscribe(wripc_handle_t handle, int event_id, int onoff)
{
uint32_t buf[4];
struct wripc_client_context *cli = get_cli_context(handle);
if(!cli)
return WRIPC_ERROR_INVALID_ARG;
if(event_id < 0 || event_id >= WRIPC_MAX_EVENTS)
return WRIPC_ERROR_INVALID_ARG;
buf[0] = MSG_TYPE_EVENT_SUBSCRIBE;
buf[1] = 16;
buf[2] = event_id;
buf[3] = onoff;
if( send(cli->fd, buf, sizeof(buf), 0) != sizeof(buf))
return WRIPC_ERROR_NETWORK_FAIL;
if(recv_with_timeout(cli->fd, buf, sizeof(buf), REPLY_TIMEOUT)
!= sizeof(buf))
return WRIPC_ERROR_MALFORMED_PACKET;
if(buf[0] != MSG_TYPE_SUBSCRIBE_ACK || buf[1] != sizeof(buf)
|| buf[2] != event_id)
return WRIPC_ERROR_MALFORMED_PACKET;
DBG("event %d", event_id);
return 0;
}
int wripc_unsubscribe_event(wripc_handle_t handle, int event_id)
{
return do_subscribe(handle, event_id, 0);
}
int wripc_subscribe_event(wripc_handle_t handle, int event_id)
{
return do_subscribe(handle, event_id, 1);
}
__attribute__((constructor)) int wripc_init()
{
//DBG("\n");
memset(handle_map, 0, sizeof(handle_map));
return 0;
}
#ifndef __WR_IPC_H
#define __WR_IPC_H
//#include <inttypes.h> -- now in ptpd-wrappers.h
#define T_INT32 1
#define T_INT16 2
#define T_INT8 3
#define T_STRING 4
#define T_FLOAT 5
#define T_DOUBLE 6
#define T_STRUCT_TYPE 7
#define T_STRUCT(type) (T_STRUCT_TYPE | (sizeof(type) << 8))
#define T_VOID 8
#define A_INT8(x) T_INT8,(x)
#define A_INT16(x) T_INT16,(x)
#define A_INT32(x) T_INT32,(x)
#define A_STRING(x) T_STRING,(x)
#define A_FLOAT(x) T_FLOAT,(x)
#define A_DOUBLE(x) T_DOUBLE,(x)
#define A_STRUCT(x) T_STRUCT(x),&x
#define WRIPC_ERROR_INVALID_REQUEST -1
#define WRIPC_ERROR_UNKNOWN_FUNCTION -2
#define WRIPC_ERROR_MALFORMED_PACKET -3
#define WRIPC_ERROR_INVALID_ARG -4
#define WRIPC_ERROR_NO_MEMORY -5
#define WRIPC_ERROR_TIMEOUT -6
#define WRIPC_ERROR_NETWORK_FAIL -7
typedef int wripc_handle_t;
wripc_handle_t wripc_create_server(const char *name);
wripc_handle_t wripc_connect(const char *name);
void wripc_close(wripc_handle_t h);
int wripc_export (wripc_handle_t handle, int rval_type, const char *name, void *func_ptr, int num_args, ...);
int wripc_call (wripc_handle_t handle, const char *name, void *rval, int num_args, ...);
int wripc_process(wripc_handle_t handle);
int wripc_publish_event(wripc_handle_t handle, int event_id, void *buf, int buf_len);
int wripc_subscribe_event(wripc_handle_t handle, int event_id);
int wripc_receive_event(wripc_handle_t handle, int *event_id, void *buf, int buf_len);
#endif
ptp-noposix @ 80b47ffe
Subproject commit 8de7f89461d772d1818bbf2bc534ac643668c2d3
Subproject commit 80b47ffe3fe7fbcb9ded920c3bbce2fa3e015fcd
......@@ -12,9 +12,9 @@ OBJDUMP = $(CROSS_COMPILE)objdump
OBJS = rtu_stat.o
CFLAGS = -O2 -I../include -DDEBUG -I$(LINUX)/include -I../libptpnetif \
-I../wrsw_hal -I../libwripc -I../wrsw_rtud -g
-I../wrsw_hal -I../wrsw_rtud -I../mini-rpc -g
LDFLAGS = -L$(WR_INSTALL_ROOT)/lib -lwripc
LDFLAGS = -L$(WR_INSTALL_ROOT)/lib -L../mini-rpc -lminipc
BINARY = rtu_stat
......
......@@ -4,15 +4,16 @@
#include <string.h>
#include <hal_client.h>
#include <minipc.h>
#include <rtud_exports.h>
#include <wr_ipc.h>
static int rtud_ipc;
static struct minipc_ch *rtud_ch;
void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from)
{
wripc_call(rtud_ipc, "rtudexp_get_fd_list", list, 1, A_INT32(start_from));
minipc_call(rtud_ch, 200, &rtud_export_get_fd_list, list,
start_from);
}
#define RTU_MAX_ENTRIES 8192
......@@ -89,9 +90,9 @@ main()
int n_entries;
int i;
rtud_ipc = wripc_connect("rtud");
rtud_ch = minipc_client_create("rtud", 0);
if(rtud_ipc < 0)
if(!rtud_ch)
{
printf("Can't conenct to RTUd wripc server\n");
return 0;
......
......@@ -13,9 +13,10 @@ OBJDUMP = $(CROSS_COMPILE)objdump
MON_OBJS = wr_mon.o term.o
CFLAGS += -O2 -DDEBUG -I$(LINUX)/include -I../include \
-I../libptpnetif -I../wrsw_hal -I../libwripc
-I../libptpnetif -I../wrsw_hal -I../mini-rpc
LDFLAGS = -L$(WR_INSTALL_ROOT)/lib -lptpnetif -lwripc
LDFLAGS = -L$(WR_INSTALL_ROOT)/lib -L../mini-rpc -L../libptpnetif \
-lptpnetif -lminipc
BINARY = wr_mon
......
#include <stdio.h>
#include <stdlib.h>
#include <wr_ipc.h>
#include <minipc.h>
#include "term.h"
#define PTP_EXPORT_STRUCTURES
#include "ptpd_exports.h"
#include "hal_client.h"
hexp_port_list_t port_list;
wripc_handle_t h_ptp;
static struct minipc_ch *ptp_ch;
void init()
{
halexp_client_init();
if( (h_ptp = wripc_connect("ptpd")) < 0)
ptp_ch = minipc_client_create("ptpd", 0);
if (!ptp_ch)
{
fprintf(stderr,"Can't establish WRIPC connection "
"to the PTP daemon!\n");
......@@ -70,7 +73,8 @@ void show_ports()
void show_servo()
{
ptpdexp_sync_state_t ss;
wripc_call(h_ptp, "ptpdexp_get_sync_state", &ss, 0);
minipc_call(ptp_ch, 200, &__rpcdef_get_sync_state, 0, &ss);
term_cprintf(C_BLUE, "\n\nSynchronization status:\n\n");
......@@ -165,9 +169,9 @@ main()
if(c=='t') {
int rval;
track_onoff = 1-track_onoff;
wripc_call(h_ptp, "ptpdexp_cmd", &rval, 2,
A_INT32(PTPDEXP_COMMAND_TRACKING),
A_INT32(track_onoff));
minipc_call(ptp_ch, 200, &__rpcdef_cmd,
&rval, PTPDEXP_COMMAND_TRACKING,
track_onoff);
}
}
......
......@@ -12,11 +12,11 @@ WR_INCLUDE = $(WR_INSTALL_ROOT)/include
WR_LIB = $(WR_INSTALL_ROOT)/lib
CFLAGS = -g -Wall -DDEBUG \
-I. -I../../../ptp-noposix-v3/libwripc -I../include -I../3rdparty/include -I$(WR_INCLUDE)
-I../include -I../mini-rpc -I$(WR_INCLUDE)
LDFLAGS = -L$(WR_INSTALL_ROOT)/lib -L../3rdparty/lib -L$(WR_LIB) \
-L../../../ptp-noposix-v3 -L../libswitchhw \
-lwripc -llua -lm -ldl -lswitchhw
-L../libswitchhw -L../mini-rpc \
-lminipc -llua -lm -ldl -lswitchhw
all: $(BINARY)
......
......@@ -8,11 +8,13 @@
#include <hw/dmpll.h>
#include "wrsw_hal.h"
#include "hal_exports.h" /* for exported structs/function protos */
#include <wr_ipc.h>
#include <minipc.h>
#define HAL_EXPORT_STRUCTURES
#include "hal_exports.h" /* for exported structs/function protos */
static wripc_handle_t hal_ipc;
static struct minipc_ch *hal_ch;
/* Dummy WRIPC export, used by the clients to check if the HAL is responding */
int halexp_check_running()
......@@ -147,26 +149,69 @@ int halexp_pll_cmd(int cmd, hexp_pll_cmd_t *params)
static void hal_cleanup_wripc()
{
wripc_close(hal_ipc);
minipc_close(hal_ch);
}
/* The functions to manage packet/args conversions */
static int export_pps_cmd(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
int rval;
/* First argument is command next is param structure */
rval = halexp_pps_cmd(args[0], (hexp_pps_params_t *)(args + 1));
*(int *)ret = rval;
return 0;
}
static int export_get_port_state(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
hexp_port_state_t *state = ret;
return halexp_get_port_state(state, (char *)args /* name */);
}
static int export_lock_cmd(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
int rval;
char *pname = (void *)args;
/* jump over the string */
args = minipc_get_next_arg(args, pd->args[0]);
rval = halexp_lock_cmd(pname, args[0] /* cmd */, args[1] /* prio */);
*(int *)ret = rval;
return 0;
}
static int export_query_ports(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
hexp_port_list_t *list = ret;
halexp_query_ports(list);
return 0;
}
/* Creates a wripc server and exports all public API functions */
int hal_init_wripc()
{
hal_ipc = wripc_create_server(WRSW_HAL_SERVER_ADDR);
hal_ch = minipc_server_create(WRSW_HAL_SERVER_ADDR, 0);
if(hal_ipc < 0)
if(hal_ch < 0)
return -1;
wripc_export(hal_ipc, T_INT32, "halexp_pps_cmd", halexp_pps_cmd, 2, T_INT32, T_STRUCT(hexp_pps_params_t));
wripc_export(hal_ipc, T_INT32, "halexp_pll_cmd", halexp_pll_cmd, 2, T_INT32, T_STRUCT(hexp_pll_cmd_t));
wripc_export(hal_ipc, T_INT32, "halexp_check_running", halexp_check_running, 0);
wripc_export(hal_ipc, T_STRUCT(hexp_port_state_t), "halexp_get_port_state", halexp_get_port_state, 1, T_STRING);
wripc_export(hal_ipc, T_INT32, "halexp_lock_cmd", halexp_lock_cmd, 3, T_STRING, T_INT32, T_INT32);
wripc_export(hal_ipc, T_STRUCT(hexp_port_list_t), "halexp_query_ports", halexp_query_ports, 0);
/* NOTE: check_running is not remotely called, so I don't export it */
/* fill the function pointers */
__rpcdef_pps_cmd.f = export_pps_cmd;
__rpcdef_get_port_state.f = export_get_port_state;
__rpcdef_lock_cmd.f = export_lock_cmd;
__rpcdef_query_ports.f = export_query_ports;
/* FIXME: pll_cmd is empty anyways???? */
hal_add_cleanup_callback(hal_cleanup_wripc);
......@@ -178,7 +223,8 @@ int hal_init_wripc()
/* wripc update function, must be called in the main program loop */
int hal_update_wripc()
{
return wripc_process(hal_ipc);
minipc_server_action(hal_ch, 200 /* ms */);
return 0;
}
......@@ -186,15 +232,11 @@ int hal_update_wripc()
launching multiple HALs simultaneously. */
int hal_check_running()
{
wripc_handle_t fd;
fd = wripc_connect(WRSW_HAL_SERVER_ADDR);
struct minipc_ch *ch;
if(fd >= 0)
{
wripc_close(fd);
return 1;
}
ch = minipc_client_create(WRSW_HAL_SERVER_ADDR, 0);
if (!ch)
return 0;
minipc_close(ch);
return 1;
}
......@@ -5,36 +5,26 @@
#define HAL_MAX_PORTS 64
/* Where do we listen for wripc requests */
#define WRSW_HAL_SERVER_ADDR "wrsw_hal"
/* Calibration call commands, handled by halexp_calibration_cmd() */
/* checks if the calibration unit is idle */
// checks if the calibration unit is idle
#define HEXP_CAL_CMD_CHECK_IDLE 1
/* enables/disables transmission of calibration patter*/
// enables/disables transmission of calibration pattern
#define HEXP_CAL_CMD_TX_PATTERN 2
/* requests the measurement of DeltaTX */
// requests a measurement of TX delta
#define HEXP_CAL_CMD_TX_MEASURE 4
/*requests a measurement of RX delta */
// requests a measurement of RX delta
#define HEXP_CAL_CMD_RX_MEASURE 5
/* get the raw delta_rx/tx (totally unprocessed - expressed as raw DMTD phase) */
#define HEXP_CAL_CMD_GET_RAW_DELTA_RX 6
#define HEXP_CAL_CMD_GET_RAW_DELTA_TX 7
/* Calibration call responses */
/* Calibrator is busy */
#define HEXP_CAL_RESP_BUSY 1
#define HEXP_CAL_RESP_OK 0
#define HEXP_CAL_RESP_ERROR -1
/* Locking call commands/responses */
#define HEXP_LOCK_CMD_START 1
#define HEXP_LOCK_CMD_CHECK 2
......@@ -42,14 +32,12 @@
#define HEXP_LOCK_STATUS_BUSY 1
#define HEXP_LOCK_STATUS_NONE 2
/* PPS Generator commands */
#define HEXP_PPSG_CMD_GET 0
#define HEXP_PPSG_CMD_ADJUST_PHASE 1
#define HEXP_PPSG_CMD_ADJUST_UTC 2
#define HEXP_PPSG_CMD_ADJUST_NSEC 3
#define HEXP_PPSG_CMD_POLL 4
/* Foreseen for halexp_pll_cmd() */
#define HEXP_ON 1
#define HEXP_OFF 0
......@@ -59,54 +47,50 @@
#define HEXP_FREQ 0
#define HEXP_PHASE 1
/* Port modes (hexp_port_state_t.mode) */
#define HEXP_PORT_MODE_WR_M_AND_S 4
#define HEXP_PORT_MODE_WR_MASTER 1
#define HEXP_PORT_MODE_WR_SLAVE 2
#define HEXP_PORT_MODE_NON_WR 3
/* External clock source control commands (temporary) */
/////////////////added by ML//////////
#define HEXP_EXTSRC_CMD_CHECK 0
#define HEXP_EXTSRC_STATUS_LOCKED 0
#define HEXP_LOCK_STATUS_BUSY 1
#define HEXP_EXTSRC_STATUS_NOSRC 2
/////////////////////////////////////
/* Number of the fractional bits in the fiber alpha coefficient - used by the PTPd servo to
avoid floating point calculations. */
#define FIX_ALPHA_FRACBITS 40
/* PPS adjustment call parameter */
typedef struct {
/* Port to be adjusted (only relevant for phase adjustment - i.e. HEXP_PPSG_CMD_ADJUST_PHASE */
char port_name[16];
/* Current value of the phase shift on port (port_name) */
uint32_t current_phase_shift;
/* Phase shift adjustment in picoseconds. Positive = future, negative = past */
int32_t adjust_phase_shift;
/* UTC/Cycle counter adjustment (seconds/nanoseconds) */
int64_t adjust_utc;
int32_t adjust_nsec;
/* Current time obtained by PPSG_GET call */
uint64_t current_utc;
uint32_t current_nsec;
} hexp_pps_params_t;
/* Port modes (hexp_port_state_t.mode) */
#define HEXP_PORT_MODE_WR_M_AND_S 4
#define HEXP_PORT_MODE_WR_MASTER 1
#define HEXP_PORT_MODE_WR_SLAVE 2
#define HEXP_PORT_MODE_NON_WR 3
#define FIX_ALPHA_FRACBITS 40
/*
#define HEXP_PORT_TSC_RISING 1
#define HEXP_PORT_TSC_FALLING 2
*/
/* Generic port state structure, filled in by halexp_get_port_state() */
typedef struct {
/* When non-zero: port state is valid */
int valid;
/* WR-PTP role of the port (Master, Slave, non-WR, etc.) */
/* WR-PTP role of the port (Master, Slave, etc.) */
int mode;
/* TX and RX delays in picoseconds (combined, big Deltas from the link model in the spec). */
/* TX and RX delays (combined, big Deltas from the link model in the spec) */
uint32_t delta_tx;
uint32_t delta_rx;
......@@ -124,73 +108,150 @@ typedef struct {
/* When non-zero: RX path is calibrated (delta_rx contains valid value) */
int rx_calibrated;
int tx_tstamp_counter;
int rx_tstamp_counter;
/* When non-zero: port is locked (i.e. the PLL is currently using it as a reference source) */
int is_locked;
/* Lock priority of the port. (0 = highest, 1 = sligtly smaller, etc).
Negative = the PLL will not use the port for clock recovery. */
int lock_priority;
// timestamp linearization paramaters
/* Current PLL phase setpoint (picoseconds). If lock_priority < 0, it's irrelevant. */
uint32_t phase_setpoint;
/* Reference clock period in picoseconds (8000 for WR). */
uint32_t clock_period;
uint32_t phase_setpoint; // DMPLL phase setpoint (picoseconds)
/* Approximate DMTD phase value (on a slave port) at which RX timestamp (T2) counter
transistion occurs (picoseconds). Used to merge the timestamp counter value with the phase value
to obtain a picosecond-level t2 timestamp. See linearize_rx_timestamp() function in libptpnetif and
Tom's M.Sc for the details of the algorithm. */
uint32_t t2_phase_transition;
uint32_t clock_period; // reference lock period in picoseconds
uint32_t t2_phase_transition; // approximate DMTD phase value (on slave port) at which RX timestamp (T2) counter transistion occurs (picoseconds)
/* The same, but for a master port. In V3 these will be identical, as there will be no physical differences
between the uplink and downlink ports */
uint32_t t4_phase_transition;
uint32_t t4_phase_transition; // approximate phase value (on master port) at which RX timestamp (T4) counter transistion occurs (picoseconds)
/* MAC address of the port */
uint8_t hw_addr[6];
/* Hardware index of the port */
int hw_index;
/* Fixed-point fiber alpha parameter, used by the PTPd to calculate the asymmetry of the fiber.
Relevant only for ports working in Slave mode.
WARNING! This is not the alpha as defined in the WR protocol specification, but a fixed point version
(which is NOT EXACTLY a floating point alpha from the spec directly converted to a fixed format by
shifting and rounding). The actual equation for obtaining fix_alpha from alpha is in hal_ports.c */
int32_t fiber_fix_alpha;
} hexp_port_state_t;
/* Port list structure. Filled in by halexp_get_port_state() */
typedef struct {
/* number of ports in port_names[][] */
int num_ports;
/* array of port names (Linux network I/Fs) */
char port_names[HAL_MAX_PORTS][16];
} hexp_port_list_t;
/* PLL command structure for halexp_pll_cmd(). To be upgraded with more parameters in the V3 */
typedef struct {
int ki, kp;
int pll;
int branch;
} hexp_pll_cmd_t;
int halexp_check_running();
int halexp_reset_port(const char *port_name);
int halexp_calibration_cmd(const char *port_name, int command, int on_off);
int halexp_lock_cmd(const char *port_name, int command, int priority);
int halexp_query_ports(hexp_port_list_t *list);
int halexp_get_port_state(hexp_port_state_t *state, const char *port_name);
int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
int halexp_pll_set_gain(int pll, int branch, int kp, int ki);
int halexp_extsrc_cmd(int command); //added by ML
/* Prototypes of functions that call on rpc */
extern int halexp_check_running(void);
extern int halexp_reset_port(const char *port_name);
extern int halexp_calibration_cmd(const char *port_name, int command, int on_off);
extern int halexp_lock_cmd(const char *port_name, int command, int priority);
extern int halexp_query_ports(hexp_port_list_t *list);
extern int halexp_get_port_state(hexp_port_state_t *state, const char *port_name);
extern int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
extern int halexp_pll_set_gain(int pll, int branch, int kp, int ki);
extern int halexp_extsrc_cmd(int command); //added by ML
/* Export structures, shared by server and client for argument matching */
#ifdef HAL_EXPORT_STRUCTURES
//int halexp_check_running();
struct minipc_pd __rpcdef_check_running = {
.name = "check_running",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_END,
},
};
//int halexp_reset_port(const char *port_name);
struct minipc_pd __rpcdef_reset_port = {
.name = "reset_port",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_END,
},
};
//int halexp_calibration_cmd(const char *port_name, int command, int on_off);
struct minipc_pd __rpcdef_calibration_cmd = {
.name = "calibration_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_lock_cmd(const char *port_name, int command, int priority);
struct minipc_pd __rpcdef_lock_cmd = {
.name = "lock_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_query_ports(hexp_port_list_t *list);
struct minipc_pd __rpcdef_query_ports = {
.name = "query_ports",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_port_list_t),
.args = {
MINIPC_ARG_END,
},
};
//int halexp_get_port_state(hexp_port_state_t *state, const char *port_name);
struct minipc_pd __rpcdef_get_port_state = {
.name = "get_port_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_port_state_t),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_END,
},
};
//int halexp_pps_cmd(int cmd, hexp_pps_params_t *params);
struct minipc_pd __rpcdef_pps_cmd = {
.name = "pps_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, hexp_pps_params_t),
MINIPC_ARG_END,
},
};
//int halexp_pll_set_gain(int pll, int branch, int kp, int ki);
struct minipc_pd __rpcdef_pll_set_gain = {
.name = "pll_set_gain",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
//int halexp_extsrc_cmd(int command); //added by ML
struct minipc_pd __rpcdef_extsrc_cmd = {
.name = "extsrc_cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
#endif /* HAL_EXPORT_STRUCTURES */
#endif
......
......@@ -10,7 +10,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <wr_ipc.h>
//#include <minipc.h>
#include <hw/trace.h>
#include <hw/switch_hw.h>
......
......@@ -15,7 +15,7 @@
#include <linux/if_arp.h>
#include <linux/if.h>
#include <wr_ipc.h>
//#include <wr_ipc.h>
/* LOTs of hardware includes */
#include <hw/trace.h>
......
......@@ -13,10 +13,12 @@ WR_INCLUDE = $(WR_INSTALL_ROOT)/include
WR_LIB = $(WR_INSTALL_ROOT)/lib
CFLAGS = -O2 -DDEBUG -Wall -ggdb -DTRACE_ALL \
-I. -I../include -I$(WR_INCLUDE) -I$(LINUX)/include
-I../libptpnetif -I../wrsw_hal \
-I../mini-rpc -I../include -I$(WR_INCLUDE) -I$(LINUX)/include
# -I$(CROSS_COMPILE_ARM_PATH)/../include
LDFLAGS := -L$(WR_LIB) -lswitchhw -lptpnetif -lwripc -lpthread
LDFLAGS := -L$(WR_LIB) -L../libptpnetif -L../libswitchhw -L../mini-rpc\
-lswitchhw -lptpnetif -lpthread -lminipc
RM := rm -f
......
......@@ -31,37 +31,24 @@
#include <stdint.h>
#include <errno.h>
#include <wr_ipc.h>
#include <hw/trace.h>
#include "minipc.h"
#include "rtu.h"
#include "rtu_fd.h"
#include "rtud_exports.h"
#include "mac.h"
static int rtud_ipc;
/* The channel */
static struct minipc_ch *rtud_ch;
int rtud_init_exports()
{
rtud_ipc = wripc_create_server("rtud");
if(rtud_ipc < 0)
return rtud_ipc;
TRACE(TRACE_INFO,"wripc server created [fd %d]", rtud_ipc);
wripc_export(rtud_ipc, T_STRUCT(rtudexp_fd_list_t), "rtudexp_get_fd_list", rtudexp_get_fd_list, 1, T_INT32);
return 0;
}
void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from)
/* The exported function */
int rtudexp_get_fd_list(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
int i;
rtudexp_fd_list_t *list = ret;
int start_from = args[0];
//TRACE(TRACE_INFO,"GetFDList start=%d",start_from);
......@@ -82,9 +69,28 @@ void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from)
list->num_rules = i;
list->next = (i < 8 ? 0 : start_from+i);
return 0;
}
int rtud_init_exports()
{
rtud_ch = minipc_server_create("rtud", 0);
if(!rtud_ch < 0)
return -1;
TRACE(TRACE_INFO,"wripc server created [fd %d]",
minipc_fileno(rtud_ch));
rtud_export_get_fd_list.f = rtudexp_get_fd_list;
if (minipc_export(rtud_ch, &rtud_export_get_fd_list) < 0)
return -1;
return 0;
}
void rtud_handle_wripc()
{
wripc_process(rtud_ipc);
minipc_server_action(rtud_ch, 100);
}
......@@ -30,6 +30,7 @@
#define __RTUD_EXPORTS_H
#include <stdint.h>
#include <minipc.h>
typedef struct
{
......@@ -47,6 +48,15 @@ typedef struct {
int next;
} rtudexp_fd_list_t;
void rtudexp_get_fd_list(rtudexp_fd_list_t *list, int start_from);
/* Export this function: it returns a structure */
struct minipc_pd rtud_export_get_fd_list = {
.name = "get_fd_list",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT,
rtudexp_fd_list_t),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_END,
},
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment