ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
sifrpc.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # (C)2001, Gustavo Scotti (gustavo@scotti.com)
7 # (c) 2003 Marcus R. Brown (mrbrown@0xd6.org)
8 # Licenced under Academic Free License version 2.0
9 # Review ps2sdk README & LICENSE files for further details.
10 */
11 
19 #include <tamtypes.h>
20 #include <ps2lib_err.h>
21 #include <kernel.h>
22 #include <sifcmd.h>
23 #include <sifrpc.h>
24 
25 #define RPC_PACKET_SIZE 64
26 
28 #define PACKET_F_ALLOC 0x01
29 
30 struct rpc_data {
31  int pid;
32  void *pkt_table;
34  int unused1;
35  int unused2;
41  void *active_queue;
42 };
43 
44 extern int _iop_reboot_count;
45 extern struct rpc_data _sif_rpc_data;
46 
49 
50 #ifdef F__rpc_get_packet
51 void *_rpc_get_packet(struct rpc_data *rpc_data)
52 {
54  int len, pid, rid = 0;
55 
56  DI();
57 
58  len = rpc_data->pkt_table_len;
59  if (len > 0) {
61 
62  for (rid = 0; rid < len; rid++, packet = (SifRpcPktHeader_t *)(((unsigned char *)packet) + RPC_PACKET_SIZE)) {
63  if (!(packet->rec_id & PACKET_F_ALLOC))
64  break;
65  }
66  if (rid == len) {
67  EI();
68  return NULL;
69  }
70 
71  pid = rpc_data->pid;
72  if (pid) {
73  rpc_data->pid = ++pid;
74  } else {
75  rpc_data->pid = pid + 2;
76  pid = 1;
77  }
78 
79  packet->rec_id = (rid << 16) | 0x04 | PACKET_F_ALLOC;
80  packet->rpc_id = pid;
81  packet->pkt_addr = packet;
82  EI();
83  return packet;
84  }
85  EI();
86  return NULL;
87 }
88 #endif
89 
90 #ifdef F__rpc_get_fpacket
91 void *_rpc_get_fpacket(struct rpc_data *rpc_data)
92 {
93  int index;
94 
97 
98  return (void *)(rpc_data->rdata_table + (index * RPC_PACKET_SIZE));
99 }
100 #endif
101 
102 #ifdef F_SifBindRpc
103 int SifBindRpc(SifRpcClientData_t *cd, int sid, int mode)
104 {
105  ee_sema_t sema;
107 
109  if (!bind)
110  return -E_SIF_PKT_ALLOC;
111 
112  cd->command = 0;
113  cd->server = NULL;
114  cd->hdr.pkt_addr = bind;
115  cd->hdr.rpc_id = bind->rpc_id;
116  cd->hdr.sema_id = -1;
117 
118  bind->sid = sid;
119  bind->pkt_addr = bind;
120  bind->client = cd;
121 
122  if (mode & SIF_RPC_M_NOWAIT) {
124  return -E_SIF_PKT_SEND;
125 
126  return 0;
127  }
128 
129  sema.max_count = 1;
130  sema.init_count = 0;
131  cd->hdr.sema_id = CreateSema(&sema);
132  if (cd->hdr.sema_id < 0)
133  return -E_LIB_SEMA_CREATE;
134 
136  return -E_SIF_PKT_SEND;
137 
138  WaitSema(cd->hdr.sema_id);
139  DeleteSema(cd->hdr.sema_id);
140 
141  return 0;
142 }
143 #endif
144 
145 #ifdef F_SifCallRpc
146 int SifCallRpc(SifRpcClientData_t *cd, int rpc_number, int mode,
147  void *sendbuf, int ssize, void *recvbuf, int rsize,
148  SifRpcEndFunc_t endfunc, void *efarg)
149 {
150  ee_sema_t sema;
151  SifRpcCallPkt_t *call;
152 
154  if (!call)
155  return -E_SIF_PKT_ALLOC;
156 
157  cd->hdr.pkt_addr = call;
158  cd->hdr.rpc_id = call->rpc_id;
159  cd->hdr.sema_id = -1;
160  cd->end_function = endfunc;
161  cd->end_param = efarg;
162 
163  call->rpc_number = rpc_number;
164  call->send_size = ssize;
165  call->receive = recvbuf;
166  call->recv_size = rsize;
167  call->rmode = 1;
168  call->pkt_addr = call;
169  call->client = cd;
170  call->server = cd->server;
171 
172  if (!(mode & SIF_RPC_M_NOWBDC)) {
173  if (ssize > 0)
174  SifWriteBackDCache(sendbuf, ssize);
175  if (rsize > 0)
176  SifWriteBackDCache(recvbuf, rsize);
177  }
178 
179  if (mode & SIF_RPC_M_NOWAIT) {
180  if (!endfunc)
181  call->rmode = 0;
182 
183  if (!SifSendCmd(SIF_CMD_RPC_CALL, call, RPC_PACKET_SIZE, sendbuf,
184  cd->buff, ssize))
185  return -E_SIF_PKT_SEND;
186 
187  return 0;
188  }
189 
190  sema.max_count = 1;
191  sema.init_count = 0;
192  cd->hdr.sema_id = CreateSema(&sema);
193  if (cd->hdr.sema_id < 0)
194  return -E_LIB_SEMA_CREATE;
195 
196  if (!SifSendCmd(SIF_CMD_RPC_CALL, call, RPC_PACKET_SIZE, sendbuf,
197  cd->buff, ssize))
198  return -E_SIF_PKT_SEND;
199 
200  WaitSema(cd->hdr.sema_id);
201  DeleteSema(cd->hdr.sema_id);
202 
203  return 0;
204 }
205 #endif
206 
207 #ifdef F_SifRpcGetOtherData
208 int SifRpcGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest,
209  int size, int mode)
210 {
211  ee_sema_t sema;
212  SifRpcOtherDataPkt_t *other;
213 
215  if (!other)
216  return -E_SIF_PKT_ALLOC;
217 
218  rd->hdr.pkt_addr = other;
219  rd->hdr.rpc_id = other->rpc_id;
220  rd->hdr.sema_id = -1;
221 
222  other->src = src;
223  other->dest = dest;
224  other->size = size;
225  other->receive = rd;
226 
227  if (mode & SIF_RPC_M_NOWAIT) {
229  return -E_SIF_PKT_SEND;
230 
231  return 0;
232  }
233 
234  sema.max_count = 1;
235  sema.init_count = 0;
236  rd->hdr.sema_id = CreateSema(&sema);
237  if (rd->hdr.sema_id < 0)
238  return -E_LIB_SEMA_CREATE;
239 
241  return -E_SIF_PKT_SEND;
242 
243  WaitSema(rd->hdr.sema_id);
244  DeleteSema(rd->hdr.sema_id);
245 
246  return 0;
247 }
248 #endif
249 
250 #ifdef F_SifRpcMain
251 
252 /* The packets sent on EE RPC requests are allocated from this table. */
253 static u8 pkt_table[2048] __attribute__((aligned(64)));
254 /* A ring buffer used to allocate packets sent on IOP requests. */
255 static u8 rdata_table[2048] __attribute__((aligned(64)));
256 static u8 client_table[2048] __attribute__((aligned(64)));
257 
258 struct rpc_data _sif_rpc_data = {
259  pid: 1,
266  rdata_table_idx: 0
267 };
268 
269 static int init = 0;
270 
271 static void rpc_packet_free(void *packet)
272 {
273  SifRpcRendPkt_t *rendpkt = (SifRpcRendPkt_t *)packet;
274 
275  rendpkt->rpc_id = 0;
276  rendpkt->rec_id &= (~PACKET_F_ALLOC);
277 }
278 
279 /* Command 0x80000008 */
280 static void _request_end(SifRpcRendPkt_t *request, void *data)
281 {
282  SifRpcClientData_t *client = request->client;
283 
284  if (request->cid == SIF_CMD_RPC_CALL) {
285  if (client->end_function)
286  client->end_function(client->end_param);
287  } else if (request->cid == SIF_CMD_RPC_BIND) {
288  client->server = request->server;
289  client->buff = request->buff;
290  client->cbuff = request->cbuff;
291  }
292 
293  if (client->hdr.sema_id >= 0)
294  iSignalSema(client->hdr.sema_id);
295 
296  rpc_packet_free(client->hdr.pkt_addr);
297  client->hdr.pkt_addr = NULL;
298 }
299 
300 static void *search_svdata(u32 sid, struct rpc_data *rpc_data)
301 {
302  SifRpcServerData_t *server;
304 
305  if (!queue)
306  return NULL;
307 
308  while (queue) {
309  server = queue->link;
310  while (server) {
311  if (server->sid == sid)
312  return server;
313 
314  server = server->link;
315  }
316 
317  queue = queue->next;
318  }
319 
320  return NULL;
321 }
322 
323 /* Command 0x80000009 */
324 static void _request_bind(SifRpcBindPkt_t *bind, void *data)
325 {
326  SifRpcRendPkt_t *rend;
327  SifRpcServerData_t *server;
328 
329  rend = _rpc_get_fpacket(data);
330  rend->pkt_addr = bind->pkt_addr;
331  rend->client = bind->client;
332  rend->cid = SIF_CMD_RPC_BIND;
333 
334  server = search_svdata(bind->sid, data);
335  if (!server) {
336  rend->server = NULL;
337  rend->buff = NULL;
338  rend->cbuff = NULL;
339  } else {
340  rend->server = server;
341  rend->buff = server->buff;
342  rend->cbuff = server->cbuff;
343  }
344 
346 }
347 
348 /* Command 0x8000000a */
349 static void _request_call(SifRpcCallPkt_t *request, void *data)
350 {
351  SifRpcServerData_t *server = request->server;
352  SifRpcDataQueue_t *base = server->base;
353 
354  if (base->start)
355  base->end->link = server;
356  else
357  base->start = server;
358 
359  base->end = server;
360  server->pkt_addr = request->pkt_addr;
361  server->client = request->client;
362  server->rpc_number = request->rpc_number;
363  server->size = request->send_size;
364  server->receive = request->receive;
365  server->rsize = request->recv_size;
366  server->rmode = request->rmode;
367  server->rid = request->rec_id;
368 
369  if (base->thread_id < 0 || base->active != 0)
370  return;
371 
372  iWakeupThread(base->thread_id);
373 }
374 
375 /* Command 0x8000000c */
376 static void _request_rdata(SifRpcOtherDataPkt_t *rdata, void *data)
377 {
378  SifRpcRendPkt_t *rend;
379 
381  rend->pkt_addr = rdata->pkt_addr;
382  rend->client = (SifRpcClientData_t *)rdata->receive;
383  rend->cid = SIF_CMD_RPC_RDATA;
384 
385  iSifSendCmd(SIF_CMD_RPC_END, rend, RPC_PACKET_SIZE, rdata->src, rdata->dest, rdata->size);
386 }
387 
388 void SifInitRpc(int mode)
389 {
390  u32 *cmdp;
391  static int _rb_count = 0;
392  if(_rb_count != _iop_reboot_count)
393  {
394  _rb_count = _iop_reboot_count;
395  SifExitCmd();
396  init = 0;
397  }
398 
399  if (init)
400  return;
401  init = 1;
402 
403  SifInitCmd();
404 
405  DI();
409 
410  SifAddCmdHandler(SIF_CMD_RPC_END, (void *)_request_end, &_sif_rpc_data);
411  SifAddCmdHandler(SIF_CMD_RPC_BIND, (void *)_request_bind, &_sif_rpc_data);
412  SifAddCmdHandler(SIF_CMD_RPC_CALL, (void *)_request_call, &_sif_rpc_data);
413  SifAddCmdHandler(SIF_CMD_RPC_RDATA, (void *)_request_rdata, &_sif_rpc_data);
414  EI();
415 
417  return;
418 
419  cmdp = (u32 *)&pkt_table[64];
420  cmdp[3] = 1;
421  SifSendCmd(SIF_CMD_INIT_CMD, cmdp, 16, NULL, NULL, 0);
422 
423  while (!SifGetSreg(SIF_SREG_RPCINIT))
424  ;
426 }
427 
428 void SifExitRpc(void)
429 {
430  SifExitCmd();
431  init = 0;
432 }
433 #endif
434 
435 #ifdef F_SifRegisterRpc
438  int sid, SifRpcFunc_t func, void *buff, SifRpcFunc_t cfunc,
439  void *cbuff, SifRpcDataQueue_t *qd)
440 {
441  SifRpcServerData_t *server;
442 
443  DI();
444 
445  sd->link = NULL;
446  sd->next = NULL;
447  sd->sid = sid;
448  sd->func = func;
449  sd->buff = buff;
450  sd->cfunc = cfunc;
451  sd->cbuff = cbuff;
452  sd->base = qd;
453 
454  if (!(server = qd->link)) {
455  qd->link = sd;
456  } else {
457  while ((server = server->next))
458  ;
459 
460  server->next = sd;
461  }
462 
463  EI();
464 
465  return server;
466 }
467 #endif
468 
469 #ifdef F_SifRemoveRpc
472 {
473  SifRpcServerData_t *server;
474 
475  DI();
476 
477  if((server = queue->link) == sd)
478  {
479  queue->link = server->link;
480  } else {
481  while(server != NULL)
482  {
483  if(server->link == sd)
484  {
485  server->link = sd->link;
486  break;
487  }
488 
489  server = server->link;
490  }
491  }
492 
493  EI();
494 
495  return server;
496 }
497 #endif
498 
499 #ifdef F_SifSetRpcQueue
501 SifSetRpcQueue(SifRpcDataQueue_t *qd, int thread_id)
502 {
503  SifRpcDataQueue_t *queue = NULL;
504 
505  DI();
506 
507  qd->thread_id = thread_id;
508  qd->active = 0;
509  qd->link = NULL;
510  qd->start = NULL;
511  qd->end = NULL;
512  qd->next = NULL;
513 
516  } else {
517  queue = _sif_rpc_data.active_queue;
518 
519  while (queue->next!=NULL) queue = queue->next;
520 
521  queue->next = qd;
522  }
523 
524  EI();
525 
526  return queue;
527 }
528 #endif
529 
530 #ifdef F_SifRemoveRpcQueue
533 {
534  SifRpcDataQueue_t *queue;
535 
536  DI();
537 
538  if((queue = _sif_rpc_data.active_queue) == qd)
539  {
541  } else {
542  while(queue != NULL)
543  {
544  if(queue->next == qd)
545  {
546  queue->next = qd->next;
547  break;
548  }
549 
550  queue = queue->next;
551  }
552  }
553 
554  EI();
555 
556  return queue;
557 }
558 #endif
559 
560 #ifdef F_SifGetNextRequest
563 {
564  SifRpcServerData_t *server;
565 
566  DI();
567 
568  server = qd->start;
569  if (server != NULL) {
570  qd->active = 1;
571  qd->start = server->next;
572  } else {
573  qd->active = 0;
574  }
575 
576  EI();
577 
578  return server;
579 }
580 #endif
581 
582 #ifdef F_SifExecRequest
583 static void *_rpc_get_fpacket2(struct rpc_data *rpc_data, int rid)
584 {
585  if (rid < 0 || rid < rpc_data->client_table_len)
586  return _rpc_get_fpacket(rpc_data);
587  else
588  return rpc_data->client_table + (rid * RPC_PACKET_SIZE);
589 }
590 
592 {
593  SifDmaTransfer_t dmat;
594  SifRpcRendPkt_t *rend;
595  void *rec = NULL;
596 
597  rec = sd->func(sd->rpc_number, sd->buff, sd->size);
598 
599  if (sd->size)
600  SifWriteBackDCache(sd->buff, sd->size);
601 
602  if (sd->rsize)
603  SifWriteBackDCache(rec, sd->rsize);
604 
605  DI();
606 
607  if (sd->rid & 4)
608  rend = (SifRpcRendPkt_t *)
609  _rpc_get_fpacket2(&_sif_rpc_data, (sd->rid >> 16) & 0xffff);
610  else
611  rend = (SifRpcRendPkt_t *)
613 
614  EI();
615 
616  rend->client = sd->client;
617  rend->cid = SIF_CMD_RPC_CALL;
618 
619  if (sd->rmode) {
620  if (!SifSendCmd(SIF_CMD_RPC_END, rend, RPC_PACKET_SIZE, rec, sd->receive,
621  sd->rsize))
622  return;
623  }
624 
625  rend->rpc_id = 0;
626  rend->rec_id = 0;
627 
628  if (sd->rsize) {
629  dmat.src = rec;
630  dmat.dest = sd->receive;
631  dmat.size = sd->rsize;
632  dmat.attr = 0;
633  } else {
634  dmat.src = rend;
635  dmat.dest = sd->pkt_addr;
636  dmat.size = 64;
637  dmat.attr = 0;
638  }
639 
640  while (!SifSetDma(&dmat, 1))
641  nopdelay();
642 }
643 #endif
644 
645 #ifdef F_SifRpcLoop
647 {
648  SifRpcServerData_t *server;
649 
650  while (1) {
651  while ((server = SifGetNextRequest(qd)))
652  SifExecRequest(server);
653 
654  SleepThread();
655  }
656 }
657 #endif
658 
659 #ifdef F_SifCheckStatRpc
661 {
662  SifRpcPktHeader_t *packet = (SifRpcPktHeader_t *)cd->hdr.pkt_addr;
663 
664  if (!packet)
665  return 0;
666 
667  if (cd->hdr.rpc_id != packet->rpc_id)
668  return 0;
669 
670  if (!(packet->rec_id & PACKET_F_ALLOC))
671  return 0;
672 
673  return 1;
674 }
675 #endif
packet_t packet
Definition: font.c:24
s32 CreateSema(ee_sema_t *sema)
s32 iWakeupThread(s32 thread_id)
s32 DeleteSema(s32 sema_id)
s32 iSignalSema(s32 sema_id)
u32 SifSetDma(SifDmaTransfer_t *sdd, s32 len)
static void nopdelay(void)
Definition: kernel.h:141
s32 WaitSema(s32 sema_id)
#define UNCACHED_SEG(x)
Definition: kernel.h:35
s32 SleepThread(void)
int SifSetReg(u32 register_num, int register_value)
#define DI
Definition: kernel.h:24
#define EI
Definition: kernel.h:25
int SifGetReg(u32 register_num)
u32 data
Definition: libmouse.c:36
s32 index
Definition: libpad.c:194
#define bind(a, b, c)
Definition: ps2ip.h:54
@ E_SIF_PKT_SEND
Definition: ps2lib_err.h:84
@ E_SIF_PKT_ALLOC
Definition: ps2lib_err.h:82
@ E_LIB_SEMA_CREATE
Definition: ps2lib_err.h:70
s32 mode
Definition: rpc_client.c:15
void SifExitCmd(void)
int SifGetSreg(int index)
unsigned int SifSendCmd(int cmd, void *packet, int packet_size, void *src_extra, void *dest_extra, int size_extra)
#define SIF_CMD_RPC_RDATA
Definition: sifcmd.h:46
#define SIF_CMD_RPC_BIND
Definition: sifcmd.h:44
void SifWriteBackDCache(void *ptr, int size)
#define SIF_CMD_RPC_END
Definition: sifcmd.h:43
#define SIF_CMD_INIT_CMD
Definition: sifcmd.h:41
void SifInitCmd(void)
#define SIF_SREG_RPCINIT
Definition: sifcmd.h:49
#define SIF_CMD_RPC_CALL
Definition: sifcmd.h:45
void SifAddCmdHandler(int pos, SifCmdHandler_t handler, void *harg)
unsigned int iSifSendCmd(int cmd, void *packet, int packet_size, void *src_extra, void *dest_extra, int size_extra)
@ SIF_SYSREG_RPCINIT
Definition: sifdma.h:41
struct rpc_data _sif_rpc_data
void * _rpc_get_packet(struct rpc_data *rpc_data)
#define RPC_PACKET_SIZE
Definition: sifrpc.c:25
int _iop_reboot_count
void * _rpc_get_fpacket(struct rpc_data *rpc_data)
#define PACKET_F_ALLOC
Definition: sifrpc.c:28
void SifInitRpc(int mode)
SifRpcServerData_t * SifRegisterRpc(SifRpcServerData_t *srv, int sid, SifRpcFunc_t func, void *buff, SifRpcFunc_t cfunc, void *cbuff, SifRpcDataQueue_t *qd)
SifRpcDataQueue_t * SifSetRpcQueue(SifRpcDataQueue_t *q, int thread_id)
int SifCheckStatRpc(SifRpcClientData_t *cd)
void SifExitRpc(void)
SifRpcServerData_t * SifRemoveRpc(SifRpcServerData_t *sd, SifRpcDataQueue_t *queue)
void SifExecRequest(SifRpcServerData_t *srv)
void SifRpcLoop(SifRpcDataQueue_t *q)
SifRpcServerData_t * SifGetNextRequest(SifRpcDataQueue_t *qd)
int SifRpcGetOtherData(SifRpcReceiveData_t *rd, void *src, void *dest, int size, int mode)
SifRpcDataQueue_t * SifRemoveRpcQueue(SifRpcDataQueue_t *qd)
#define SIF_RPC_M_NOWAIT
Definition: sifrpc.h:24
int SifBindRpc(SifRpcClientData_t *client, int rpc_number, int mode)
void(* SifRpcEndFunc_t)(void *end_param)
Definition: sifrpc.h:33
void *(* SifRpcFunc_t)(int fno, void *buffer, int length)
Definition: sifrpc.h:32
#define SIF_RPC_M_NOWBDC
Definition: sifrpc.h:26
int SifCallRpc(SifRpcClientData_t *client, int rpc_number, int mode, void *send, int ssize, void *receive, int rsize, SifRpcEndFunc_t end_function, void *end_param)
static SifRpcDataQueue_t qd
Definition: sior_rpc.c:27
void * dest
Definition: sifdma.h:55
void * src
Definition: sifdma.h:54
int recv_size
Definition: sifrpc.h:93
struct t_SifRpcClientData * client
Definition: sifrpc.h:89
int send_size
Definition: sifrpc.h:91
int rpc_number
Definition: sifrpc.h:90
void * pkt_addr
Definition: sifrpc.h:87
void * receive
Definition: sifrpc.h:92
struct t_SifRpcServerData * server
Definition: sifrpc.h:95
struct t_SifRpcServerData * server
Definition: sifrpc.h:142
SifRpcEndFunc_t end_function
Definition: sifrpc.h:140
void * end_param
Definition: sifrpc.h:141
struct t_SifRpcHeader hdr
Definition: sifrpc.h:136
struct t_SifRpcServerData * end
Definition: sifrpc.h:159
struct t_SifRpcServerData * start
Definition: sifrpc.h:158
struct t_SifRpcDataQueue * next
Definition: sifrpc.h:160
struct t_SifRpcServerData * link
Definition: sifrpc.h:157
struct t_SifRpcReceiveData * receive
Definition: sifrpc.h:67
struct t_SifRpcHeader hdr
Definition: sifrpc.h:147
void * cbuff
Definition: sifrpc.h:57
void * buff
Definition: sifrpc.h:56
void * pkt_addr
Definition: sifrpc.h:50
struct t_SifRpcServerData * server
Definition: sifrpc.h:55
struct t_SifRpcClientData * client
Definition: sifrpc.h:53
struct t_SifRpcServerData * link
Definition: sifrpc.h:119
void * receive
Definition: sifrpc.h:114
SifRpcFunc_t cfunc
Definition: sifrpc.h:106
struct t_SifRpcServerData * next
Definition: sifrpc.h:120
void * pkt_addr
Definition: sifrpc.h:111
struct t_SifRpcDataQueue * base
Definition: sifrpc.h:121
SifRpcFunc_t func
Definition: sifrpc.h:102
struct t_SifRpcClientData * client
Definition: sifrpc.h:110
int init_count
Definition: kernel.h:218
int max_count
Definition: kernel.h:217
Definition: thread.c:17
int rdata_table_len
Definition: sifrpc.c:37
int client_table_len
Definition: sifrpc.c:39
int unused2
Definition: sifrpc.c:35
int rdata_table_idx
Definition: sifrpc.c:40
u8 * client_table
Definition: sifrpc.c:38
int pkt_table_len
Definition: sifrpc.c:33
int unused1
Definition: sifrpc.c:34
void * active_queue
Definition: sifrpc.c:41
int pid
Definition: sifrpc.c:31
u8 * rdata_table
Definition: sifrpc.c:36
void * pkt_table
Definition: sifrpc.c:32
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned char u8
Definition: tamtypes.h:23