PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
ps2ipc.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
16#include <tamtypes.h>
17#include <string.h>
18#include <kernel.h>
19#include <sifrpc.h>
20
21#include <ps2ips.h>
22#include <ps2ip_rpc.h>
23
24static int _init_check = 0;
25static int lock_sema = -1;
26static SifRpcClientData_t _ps2ip;
27static struct {
28 union {
29 s32 result;
30 s32 s; //Generic socket parameter.
31 cmd_pkt cmd_pkt; //Generic command packet, used by multiple functions.
37 t_ip_info ip_info;
38 char netif_name[8];
44 char hostname[256];
45 gethostbyname_res_pkt gethostbyname_res_pkt;
46 dns_setserver_pkt dns_setserver_pkt;
47 dns_getserver_res_pkt dns_getserver_res_pkt;
48 u8 numdns;
49 u8 buffer[512];
50 };
51} _rpc_buffer __attribute__((aligned(64)));
52static int _intr_data[32] __attribute__((aligned(64)));
53
54static ip_addr_t dns_servers[DNS_MAX_SERVERS];
55
56//Copied from LWIP, to be independent of the full LWIP source.
57/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
58const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
59
60/* The following are defined in ps2ipc_ps2sdk.c */
61extern void _ps2sdk_ps2ipc_init(void);
62extern void _ps2sdk_ps2ipc_deinit(void);
63
64int ps2ip_init(void)
65{
66 ee_sema_t sema;
67
68 while(1)
69 {
70 if(SifBindRpc(&_ps2ip, PS2IP_IRX, 0) < 0)
71 return -1;
72
73 if(_ps2ip.server != NULL)
74 break;
75
76 nopdelay();
77 }
78
79 sema.init_count = 1;
80 sema.max_count = 1;
81 sema.option = (u32)"ps2ipc";
82 sema.attr = 0;
83 lock_sema = CreateSema(&sema);
84
85 _ps2sdk_ps2ipc_init();
86
87 _init_check = 1;
88
89 return 0;
90}
91
92void ps2ip_deinit(void)
93{
94 _ps2sdk_ps2ipc_deinit();
95
96 if (lock_sema >= 0)
97 DeleteSema(lock_sema);
98 lock_sema = -1;
99
100 _init_check = 0;
101}
102
103int ps2ipc_accept(int s, struct sockaddr *addr, int *addrlen)
104{
105 int result;
106 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
107
108 if(!_init_check) return -1;
109
110 WaitSema(lock_sema);
111
112 pkt->socket = s;
113
114 if (SifCallRpc(&_ps2ip, PS2IPS_ID_ACCEPT, 0, (void*)pkt, sizeof(s32), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
115 {
116 SignalSema(lock_sema);
117 return -1;
118 }
119
120 if(addr != NULL)
121 {
122 if(pkt->len < *addrlen) *addrlen = pkt->len;
123 memcpy((void *)addr, (void *)&pkt->sockaddr, *addrlen);
124 }
125
126 result = pkt->socket;
127
128 SignalSema(lock_sema);
129
130 return result;
131}
132
133int ps2ipc_bind(int s, const struct sockaddr *name, int namelen)
134{
135 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
136 int result;
137
138 if(!_init_check) return -1;
139
140 WaitSema(lock_sema);
141
142 pkt->socket = s;
143 pkt->len = namelen;
144 memcpy((void *)&pkt->sockaddr, (void *)name, sizeof(struct sockaddr));
145
146 if (SifCallRpc(&_ps2ip, PS2IPS_ID_BIND, 0, (void*)pkt, sizeof(cmd_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
147 {
148 SignalSema(lock_sema);
149 return -1;
150 }
151
152 result = _rpc_buffer.result;
153
154 SignalSema(lock_sema);
155
156 return result;
157}
158
159int ps2ipc_disconnect(int s)
160{
161 int result;
162
163 if(!_init_check) return -1;
164
165 WaitSema(lock_sema);
166
167 _rpc_buffer.s = s;
168
169 if (SifCallRpc(&_ps2ip, PS2IPS_ID_DISCONNECT, 0, (void*)&_rpc_buffer.s, sizeof(s32), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
170 {
171 SignalSema(lock_sema);
172 return -1;
173 }
174
175 result = _rpc_buffer.result;
176
177 SignalSema(lock_sema);
178
179 return result;
180}
181
182int ps2ipc_connect(int s, const struct sockaddr *name, int namelen)
183{
184 int result;
185 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
186
187 if(!_init_check) return -1;
188
189 WaitSema(lock_sema);
190
191 pkt->socket = s;
192 pkt->len = namelen;
193 memcpy((void *)&pkt->sockaddr, (void *)name, sizeof(struct sockaddr));
194
195 if (SifCallRpc(&_ps2ip, PS2IPS_ID_CONNECT, 0, (void*)pkt, sizeof(cmd_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
196 {
197 SignalSema(lock_sema);
198 return -1;
199 }
200
201 result = _rpc_buffer.result;
202
203 SignalSema(lock_sema);
204
205 return result;
206}
207
208int ps2ipc_listen(int s, int backlog)
209{
210 int result;
211 listen_pkt *pkt = &_rpc_buffer.listen_pkt;
212
213 if(!_init_check) return -1;
214
215 WaitSema(lock_sema);
216
217 pkt->s = s;
218 pkt->backlog = backlog;
219
220 if (SifCallRpc(&_ps2ip, PS2IPS_ID_LISTEN, 0, (void*)pkt, sizeof(listen_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
221 {
222 SignalSema(lock_sema);
223 return -1;
224 }
225
226 result = _rpc_buffer.result;
227
228 SignalSema(lock_sema);
229
230 return result;
231}
232
233static void recv_intr(void *data_raw)
234{
235 rests_pkt *rests = UNCACHED_SEG(data_raw);
236 int i;
237
238 if(rests->ssize)
239 for(i = 0; i < rests->ssize; i++)
240 rests->sbuf[i] = rests->sbuffer[i];
241
242 if(rests->esize)
243 for(i = 0; i < rests->esize; i++)
244 rests->ebuf[i] = rests->ebuffer[i];
245}
246
247
248int ps2ipc_recv(int s, void *mem, int len, unsigned int flags)
249{
250 int result;
251 s_recv_pkt *send_pkt = &_rpc_buffer.s_recv_pkt;
252 r_recv_pkt *recv_pkt = &_rpc_buffer.r_recv_pkt;
253
254 if(!_init_check) return -1;
255
256 WaitSema(lock_sema);
257
258 send_pkt->socket = s;
259 send_pkt->length = len;
260 send_pkt->flags = flags;
261 send_pkt->ee_addr = mem;
262 send_pkt->intr_data = _intr_data;
263
264 if( !IS_UNCACHED_SEG(mem))
265 SifWriteBackDCache(mem, len);
266
267 if (SifCallRpc(&_ps2ip, PS2IPS_ID_RECV, 0, (void*)send_pkt, sizeof(s_recv_pkt),
268 (void*)recv_pkt, sizeof(r_recv_pkt), recv_intr, _intr_data) < 0)
269 {
270 SignalSema(lock_sema);
271 return -1;
272 }
273
274 result = recv_pkt->ret;
275
276 SignalSema(lock_sema);
277
278 return result;
279}
280
281int ps2ipc_recvfrom(int s, void *mem, int len, unsigned int flags,
282 struct sockaddr *from, int *fromlen)
283{
284 int result;
285 s_recv_pkt *send_pkt = &_rpc_buffer.s_recv_pkt;
286 r_recv_pkt *recv_pkt = &_rpc_buffer.r_recv_pkt;
287
288 if(!_init_check) return -1;
289
290 WaitSema(lock_sema);
291
292 send_pkt->socket = s;
293 send_pkt->length = len;
294 send_pkt->flags = flags;
295 send_pkt->ee_addr = mem;
296 send_pkt->intr_data = _intr_data;
297
298 if( !IS_UNCACHED_SEG(mem))
299 SifWriteBackDCache(mem, len);
300
301 if (SifCallRpc(&_ps2ip, PS2IPS_ID_RECVFROM, 0, (void*)send_pkt, sizeof(s_recv_pkt),
302 (void*)recv_pkt, sizeof(r_recv_pkt), recv_intr, _intr_data) < 0)
303 {
304 SignalSema(lock_sema);
305 return -1;
306 }
307
308 memcpy((void *)from, (void *)&recv_pkt->sockaddr, sizeof(struct sockaddr));
309 *fromlen = sizeof(struct sockaddr);
310
311 result = recv_pkt->ret;
312
313 SignalSema(lock_sema);
314
315 return result;
316}
317
318int ps2ipc_send(int s, const void *dataptr, int size, unsigned int flags)
319{
320 int result;
321 send_pkt *pkt = &_rpc_buffer.send_pkt;
322 int miss;
323
324 WaitSema(lock_sema);
325
326 pkt->socket = s;
327 pkt->length = size;
328 pkt->flags = flags;
329 pkt->ee_addr = (void *)dataptr;
330
331 if((u32)dataptr & 0x3f)
332 {
333 miss = 64 - ((u32)dataptr & 0x3f);
334 if(miss > size) miss = size;
335
336 } else {
337
338 miss = 0;
339 }
340
341 pkt->malign = miss;
342
343 if( !IS_UNCACHED_SEG(dataptr))
344 SifWriteBackDCache((void *)dataptr, size);
345
346 memcpy((void *)pkt->malign_buff, UNCACHED_SEG(dataptr), miss);
347
348 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SEND, 0, (void*)pkt, sizeof(send_pkt),
349 (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
350 {
351 SignalSema(lock_sema);
352 return -1;
353 }
354
355 result = _rpc_buffer.result;
356
357 SignalSema(lock_sema);
358
359 return result;
360}
361
362int ps2ipc_sendto(int s, const void *dataptr, int size, unsigned int flags,
363 const struct sockaddr *to, int tolen)
364{
365 int result;
366 send_pkt *pkt = &_rpc_buffer.send_pkt;
367 int miss;
368
369 (void)tolen;
370
371 WaitSema(lock_sema);
372
373 pkt->socket = s;
374 pkt->length = size;
375 pkt->flags = flags;
376 pkt->ee_addr = (void *)dataptr;
377 memcpy((void *)&pkt->sockaddr, (void *)to, sizeof(struct sockaddr));
378
379 if((u32)dataptr & 0x3f)
380 {
381 miss = 64 - ((u32)dataptr & 0x3f);
382 if(miss > size) miss = size;
383
384 } else {
385
386 miss = 0;
387 }
388
389 pkt->malign = miss;
390
391 if( !IS_UNCACHED_SEG(dataptr))
392 SifWriteBackDCache((void *)dataptr, size);
393
394 memcpy((void *)pkt->malign_buff, UNCACHED_SEG(dataptr), miss);
395
396 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SENDTO, 0, (void*)pkt, sizeof(send_pkt),
397 (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
398 {
399 SignalSema(lock_sema);
400 return -1;
401 }
402
403 result = _rpc_buffer.result;
404
405 SignalSema(lock_sema);
406
407 return result;
408}
409
410int ps2ipc_socket(int domain, int type, int protocol)
411{
412 int result;
413 socket_pkt *pkt = &_rpc_buffer.socket_pkt;
414
415 if(!_init_check) return -1;
416
417 WaitSema(lock_sema);
418
419 pkt->domain = domain;
420 pkt->type = type;
421 pkt->protocol = protocol;
422
423 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SOCKET, 0, (void*)pkt, sizeof(socket_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
424 {
425 SignalSema(lock_sema);
426 return -1;
427 }
428
429 result = _rpc_buffer.result;
430
431 SignalSema(lock_sema);
432
433 return result;
434}
435
436int ps2ipc_ps2ip_setconfig(const t_ip_info *ip_info)
437{
438 int result;
439
440 if(!_init_check) return -1;
441
442 WaitSema(lock_sema);
443
444 // return config
445 memcpy(&_rpc_buffer.ip_info, ip_info, sizeof(t_ip_info));
446
447 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SETCONFIG, 0, (void*)&_rpc_buffer.ip_info, sizeof(t_ip_info), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
448 {
449 SignalSema(lock_sema);
450 return -1;
451 }
452
453 result = _rpc_buffer.result;
454
455 SignalSema(lock_sema);
456
457 return result;
458}
459
460int ps2ipc_ps2ip_getconfig(char *netif_name, t_ip_info *ip_info)
461{
462 if(!_init_check) return -1;
463
464 WaitSema(lock_sema);
465
466 // call with netif name
467 strncpy(_rpc_buffer.netif_name, netif_name, sizeof(_rpc_buffer.netif_name));
468 _rpc_buffer.netif_name[sizeof(_rpc_buffer.netif_name) - 1] = '\0';
469
470 if (SifCallRpc(&_ps2ip, PS2IPS_ID_GETCONFIG, 0, (void*)_rpc_buffer.netif_name, sizeof(_rpc_buffer.netif_name), (void*)&_rpc_buffer.ip_info, sizeof(t_ip_info), NULL, NULL) < 0)
471 {
472 SignalSema(lock_sema);
473 return -1;
474 }
475
476 // return config
477 memcpy(ip_info, &_rpc_buffer.ip_info, sizeof(t_ip_info));
478
479 SignalSema(lock_sema);
480
481 return 1;
482}
483
484int ps2ipc_select(int maxfdp1, struct fd_set *readset, struct fd_set *writeset, struct fd_set *exceptset, struct timeval *timeout)
485{
486 int result;
487 select_pkt *pkt = &_rpc_buffer.select_pkt;
488
489 if(!_init_check) return -1;
490
491 WaitSema(lock_sema);
492
493 pkt->maxfdp1 = maxfdp1;
494 pkt->readset_p = readset;
495 pkt->writeset_p = writeset;
496 pkt->exceptset_p = exceptset;
497 pkt->timeout_p = timeout;
498 if( timeout )
499 pkt->timeout = *timeout;
500
501 if( readset )
502 pkt->readset = *readset;
503
504 if( writeset )
505 pkt->writeset = *writeset;
506
507 if( exceptset )
508 pkt->exceptset = *exceptset;
509
510 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SELECT, 0, (void*)pkt, sizeof(select_pkt), (void*)pkt, sizeof(select_pkt), NULL, NULL) < 0)
511 {
512 SignalSema(lock_sema);
513 return -1;
514 }
515
516 if( timeout )
517 *timeout = pkt->timeout;
518
519 if( readset )
520 *readset = pkt->readset;
521
522 if( writeset )
523 *writeset = pkt->writeset;
524
525 if( exceptset )
526 *exceptset = pkt->exceptset;
527
528 result = pkt->result;
529
530 SignalSema(lock_sema);
531
532 return result;
533}
534
535int ps2ipc_ioctl(int s, long cmd, void *argp)
536{
537 int result;
538 ioctl_pkt *pkt = &_rpc_buffer.ioctl_pkt;
539
540 if(!_init_check) return -1;
541
542 WaitSema(lock_sema);
543
544 pkt->s = s;
545 pkt->cmd = (s32)cmd;
546 pkt->argp = argp;
547 if( argp )
548 pkt->value = *(s32*)argp;
549
550 if (SifCallRpc(&_ps2ip, PS2IPS_ID_IOCTL, 0, (void*)pkt, sizeof(ioctl_pkt), (void*)pkt, sizeof(ioctl_pkt), NULL, NULL) < 0)
551 {
552 SignalSema(lock_sema);
553 return -1;
554 }
555
556 if( argp )
557 *(s32*)argp = pkt->value;
558
559 result = pkt->result;
560
561 SignalSema(lock_sema);
562
563 return result;
564}
565
566int ps2ipc_getsockname(int s, struct sockaddr *name, int *namelen)
567{
568 int result;
569 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
570
571 if(!_init_check) return -1;
572
573 WaitSema(lock_sema);
574
575 pkt->socket = s;
576
577 if (SifCallRpc(&_ps2ip, PS2IPS_ID_GETSOCKNAME, 0, (void*)pkt, sizeof(pkt->socket), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
578 {
579 SignalSema(lock_sema);
580 return -1;
581 }
582
583 if(pkt->len < *namelen) *namelen = pkt->len;
584 memcpy((void *)name, (void *)&pkt->sockaddr, *namelen);
585
586 result = pkt->socket;
587
588 SignalSema(lock_sema);
589
590 return result;
591}
592
593int ps2ipc_getpeername(int s, struct sockaddr *name, int *namelen)
594{
595 int result;
596 cmd_pkt *pkt = &_rpc_buffer.cmd_pkt;
597
598 if(!_init_check) return -1;
599
600 WaitSema(lock_sema);
601
602 pkt->socket = s;
603
604 if (SifCallRpc(&_ps2ip, PS2IPS_ID_GETPEERNAME, 0, (void*)pkt, sizeof(pkt->socket), (void*)pkt, sizeof(cmd_pkt), NULL, NULL) < 0)
605 {
606 SignalSema(lock_sema);
607 return -1;
608 }
609
610 if(pkt->len < *namelen) *namelen = pkt->len;
611 memcpy((void *)name, (void *)&pkt->sockaddr, *namelen);
612
613 result = pkt->socket;
614
615 SignalSema(lock_sema);
616
617 return result;
618}
619
620int ps2ipc_getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
621{
622 getsockopt_pkt *pkt = &_rpc_buffer.getsockopt_pkt;
623 getsockopt_res_pkt *res_pkt = &_rpc_buffer.getsockopt_res_pkt;
624 int result;
625
626 if(!_init_check) return -1;
627
628 WaitSema(lock_sema);
629
630 pkt->s = s;
631 pkt->level = level;
632 pkt->optname = optname;
633
634 if (SifCallRpc(&_ps2ip, PS2IPS_ID_GETSOCKOPT, 0, (void*)pkt, sizeof(getsockopt_pkt), (void*)res_pkt, sizeof(getsockopt_res_pkt), NULL, NULL) < 0)
635 {
636 SignalSema(lock_sema);
637 return -1;
638 }
639
640 if(res_pkt->optlen < *optlen) *optlen = res_pkt->optlen;
641 memcpy((void*)optval, res_pkt->buffer, *optlen);
642
643 result = res_pkt->result;
644
645 SignalSema(lock_sema);
646
647 return result;
648}
649
650int ps2ipc_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
651{
652 setsockopt_pkt *pkt = &_rpc_buffer.setsockopt_pkt;
653 int result;
654
655 if(!_init_check) return -1;
656
657 WaitSema(lock_sema);
658
659 pkt->s = s;
660 pkt->level = level;
661 pkt->optname = optname;
662 pkt->optlen = optlen;
663
664 memcpy(pkt->buffer, optval, optlen);
665
666 if (SifCallRpc(&_ps2ip, PS2IPS_ID_SETSOCKOPT, 0, (void*)pkt, sizeof(setsockopt_pkt), (void*)&_rpc_buffer.result, sizeof(s32), NULL, NULL) < 0)
667 {
668 SignalSema(lock_sema);
669 return -1;
670 }
671
672 result = _rpc_buffer.result;
673
674 SignalSema(lock_sema);
675
676 return result;
677}
678
679#ifdef PS2IP_DNS
680struct hostent *ps2ipc_gethostbyname(const char *name)
681{
682 gethostbyname_res_pkt *res_pkt = &_rpc_buffer.gethostbyname_res_pkt;
683 struct hostent *result;
684 static ip_addr_t addr;
685 static ip_addr_t *addr_list[2];
686 static struct hostent hostent;
687
688 if(!_init_check) return NULL;
689
690 WaitSema(lock_sema);
691
692 result = NULL;
693 strncpy(_rpc_buffer.hostname, name, sizeof(_rpc_buffer.hostname));
694 _rpc_buffer.hostname[sizeof(_rpc_buffer.hostname) - 1] = '\0';
695 if(SifCallRpc(&_ps2ip, PS2IPS_ID_GETHOSTBYNAME, 0, (void*)_rpc_buffer.hostname, sizeof(_rpc_buffer.hostname), (void*)res_pkt, sizeof(gethostbyname_res_pkt), NULL, NULL) >=0)
696 {
697 if(res_pkt->result == 0)
698 {
699 hostent.h_addrtype = res_pkt->hostent.h_addrtype;
700 hostent.h_length = res_pkt->hostent.h_length;
701 hostent.h_name = (char*)name;
702 hostent.h_aliases = NULL;
703 memcpy(&addr, &res_pkt->hostent.h_addr, sizeof(addr));
704 addr_list[0] = &addr;
705 addr_list[1] = NULL;
706 hostent.h_addr_list = (char**)&addr_list;
707 result = &hostent;
708 }
709 }
710
711 SignalSema(lock_sema);
712
713 return result;
714}
715
716void ps2ipc_dns_setserver(u8 numdns, const ip_addr_t *dnsserver)
717{
718 dns_setserver_pkt *pkt = &_rpc_buffer.dns_setserver_pkt;
719
720 if(!_init_check) return;
721
722 WaitSema(lock_sema);
723
724 pkt->numdns = numdns;
725 pkt->dnsserver = (dnsserver != NULL) ? (*dnsserver) : *IP4_ADDR_ANY;
726
727 SifCallRpc(&_ps2ip, PS2IPS_ID_DNS_SETSERVER, 0, (void*)pkt, sizeof(dns_setserver_pkt), NULL, 0, NULL, NULL);
728
729 if (numdns < DNS_MAX_SERVERS)
730 dns_servers[numdns] = (dnsserver != NULL) ? (*dnsserver) : *IP4_ADDR_ANY;
731
732 SignalSema(lock_sema);
733}
734
735const ip_addr_t *ps2ipc_dns_getserver(u8 numdns)
736{
737 dns_getserver_res_pkt *res_pkt = &_rpc_buffer.dns_getserver_res_pkt;
738 ip_addr_t *dns;
739
740 if ((!_init_check) || (numdns >= DNS_MAX_SERVERS))
741 return IP4_ADDR_ANY;
742
743 WaitSema(lock_sema);
744
745 _rpc_buffer.numdns = numdns;
746 dns = &dns_servers[numdns];
747
748 //If this fails, use the cached copy.
749 if(SifCallRpc(&_ps2ip, PS2IPS_ID_DNS_GETSERVER, 0, (void*)&_rpc_buffer.numdns, sizeof(u8), (void*)res_pkt, sizeof(dns_getserver_res_pkt), NULL, NULL) >=0)
750 ip_addr_copy(*dns, res_pkt->dnsserver);
751
752 SignalSema(lock_sema);
753
754 return dns;
755}
756#endif
u8 malign_buff[64]
Definition ps2ip_rpc.h:75
#define IPADDR_ANY
Definition tcpip.h:251
#define IP4_ADDR_ANY
Definition tcpip.h:1015
Definition time.h:29