00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <u/libu.h>
00013 #include <klone/ppc.h>
00014
00015 struct ppc_header_s
00016 {
00017 unsigned char cmd;
00018 size_t size;
00019 };
00020
00021 typedef struct ppc_header_s ppc_header_t;
00022
00023 struct ppc_s
00024 {
00025 ppc_cb_t ftb[256];
00026 void *arg[256];
00027 };
00028
00029 int ppc_register(ppc_t *ppc, unsigned char cmd, ppc_cb_t cb, void *arg)
00030 {
00031 dbg_err_if (ppc == NULL);
00032 dbg_err_if (cb == NULL);
00033
00034 ppc->ftb[cmd] = cb;
00035 ppc->arg[cmd] = arg;
00036
00037 return 0;
00038 err:
00039 return ~0;
00040 }
00041
00042 static ssize_t ppc_do_read(int fd, char *data, size_t size)
00043 {
00044 ssize_t n;
00045
00046 dbg_return_if (fd < 0, -1);
00047 dbg_return_if (data == NULL, -1);
00048
00049 again:
00050 n = read(fd, data, size);
00051 if(n < 0 && errno == EINTR)
00052 goto again;
00053
00054 return n;
00055 }
00056
00057 static ssize_t ppc_do_write(int fd, char *data, size_t size)
00058 {
00059 ssize_t n;
00060
00061 dbg_return_if (fd < 0, -1);
00062 dbg_return_if (data == NULL, -1);
00063
00064 again:
00065 n = write(fd, data, size);
00066 if(n < 0 && errno == EINTR)
00067 goto again;
00068
00069 return n;
00070 }
00071
00072 ssize_t ppc_write(ppc_t *ppc, int fd, unsigned char cmd, char *data,
00073 size_t size)
00074 {
00075 ssize_t n;
00076 ppc_header_t h;
00077
00078 dbg_return_if (ppc == NULL, -1);
00079 dbg_return_if (data == NULL, -1);
00080 dbg_return_if (fd < 0, -1);
00081
00082 memset(&h, 0, sizeof(ppc_header_t));
00083 h.cmd = cmd;
00084 h.size = size;
00085
00086 n = ppc_do_write(fd, (char*)&h, sizeof(ppc_header_t));
00087 if(n <= 0)
00088 return n;
00089
00090 n = ppc_do_write(fd, data, size);
00091 if(n <= 0)
00092 return n;
00093
00094 return 1;
00095 }
00096
00097 ssize_t ppc_read(ppc_t *ppc, int fd, unsigned char *pcmd, char *data,
00098 size_t size)
00099 {
00100 ppc_header_t h;
00101 ssize_t n;
00102
00103 dbg_return_if (ppc == NULL, -1);
00104 dbg_return_if (pcmd == NULL, -1);
00105 dbg_return_if (data == NULL, -1);
00106 dbg_return_if (fd < 0, -1);
00107
00108 n = ppc_do_read(fd, (char*)&h, sizeof(ppc_header_t));
00109 if(n <= 0)
00110 return n;
00111
00112
00113 dbg_return_ifm (h.size > size || h.size > PPC_MAX_DATA_SIZE, -1,
00114 "ppc error h.cmd: %d, h.size: %lu", h.cmd, (unsigned long) h.size);
00115
00116 n = ppc_do_read(fd, data, h.size);
00117 if(n <= 0)
00118 return n;
00119
00120 *pcmd = h.cmd;
00121
00122 return h.size;
00123 }
00124
00125 int ppc_dispatch(ppc_t *ppc, int fd, unsigned char cmd, char *data, size_t size)
00126 {
00127 dbg_err_if (ppc == NULL);
00128 dbg_err_if (ppc->ftb[cmd] == NULL);
00129
00130 ppc->ftb[cmd](ppc, fd, cmd, data, size, ppc->arg[cmd]);
00131
00132 return 0;
00133 err:
00134 return ~0;
00135 }
00136
00137 int ppc_free(ppc_t *ppc)
00138 {
00139 U_FREE(ppc);
00140 return 0;
00141 }
00142
00143 int ppc_create(ppc_t **pppc)
00144 {
00145 ppc_t *ppc = NULL;
00146
00147 dbg_err_if (pppc == NULL);
00148
00149 ppc = u_zalloc(sizeof(ppc_t));
00150 dbg_err_if(ppc == NULL);
00151
00152 *pppc = ppc;
00153
00154 return 0;
00155 err:
00156 return ~0;
00157 }
00158