Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / debug / ps2link / net_fio.c
blob169c17b80e788245d7044edc3064b520d4c18b0b
1 /*********************************************************************
2 * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
3 * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
4 * This file is subject to the terms and conditions of the PS2Link License.
5 * See the file LICENSE in the main directory of this distribution for more
6 * details.
7 */
9 // Fu*k knows why net_fio & net_fsys are separated..
11 #include <types.h>
12 #include <ioman.h>
13 #include <sysclib.h>
14 #include <stdio.h>
15 #include <thbase.h>
17 #include <io_common.h>
19 #include "ps2ip.h"
20 #include "net_fio.h"
21 #include "hostlink.h"
23 #define ntohl(x) htonl(x)
24 #define ntohs(x) htons(x)
26 unsigned int remote_pc_addr = 0xffffffff;
28 #define PACKET_MAXSIZE 4096
30 static char send_packet[PACKET_MAXSIZE] __attribute__((aligned(16)));
31 static char recv_packet[PACKET_MAXSIZE] __attribute__((aligned(16)));
33 static int pko_fileio_sock = -1;
34 static int pko_fileio_active = 0;
36 #ifdef DEBUG
37 #define dbgprintf(args...) printf(args)
38 #else
39 #define dbgprintf(args...) do { } while(0)
40 #endif
42 //----------------------------------------------------------------------
44 void
45 pko_close_socket(void)
47 int ret;
49 ret = disconnect(pko_fileio_sock);
50 if (ret < 0) {
51 printf("pko_file: disconnect returned error %d\n", ret);
53 pko_fileio_sock = -1;
56 //----------------------------------------------------------------------
58 void
59 pko_close_fsys(void)
61 if (pko_fileio_sock > 0) {
62 disconnect(pko_fileio_sock);
64 pko_fileio_active = 0;
65 return;
68 //----------------------------------------------------------------------
69 // XXX: Hm, this func should behave sorta like pko_recv_bytes imho..
70 // i.e. check if it was able to send just a part of the packet etc..
71 static inline int
72 pko_lwip_send(int sock, void *buf, int len, int flag)
74 int ret;
75 ret = send(sock, buf, len, flag);
76 if (ret < 0) {
77 dbgprintf("pko_file: lwip_send() error %d\n", ret);
78 pko_close_socket();
79 return -1;
81 else {
82 return ret;
87 //----------------------------------------------------------------------
88 // Do repetetive recv() calles until 'bytes' bytes are received
89 // or error returned
90 int pko_recv_bytes(int sock, char *buf, int bytes)
92 int left;
93 int len;
95 left = bytes;
97 while (left > 0) {
98 len = recv(sock, &buf[bytes - left], left, 0);
99 if (len < 0) {
100 dbgprintf("pko_file: pko_recv_bytes error!!\n");
101 return -1;
103 left -= len;
105 return bytes;
109 //----------------------------------------------------------------------
110 // Receive a 'packet' of the expected type 'pkt_type', and lenght 'len'
111 int pko_accept_pkt(int sock, char *buf, int len, int pkt_type)
113 int length;
114 pko_pkt_hdr *hdr;
115 unsigned int hcmd;
116 unsigned short hlen;
119 length = pko_recv_bytes(sock, buf, sizeof(pko_pkt_hdr));
120 if (length < 0) {
121 dbgprintf("pko_file: accept_pkt recv error\n");
122 return -1;
125 if (length < sizeof(pko_pkt_hdr)) {
126 dbgprintf("pko_file: XXX: did not receive a full header!!!! "
127 "Fix this! (%d)\n", length);
130 hdr = (pko_pkt_hdr *)buf;
131 hcmd = ntohl(hdr->cmd);
132 hlen = ntohs(hdr->len);
134 if (hcmd != pkt_type) {
135 dbgprintf("pko_file: pko_accept_pkt: Expected %x, got %x\n",
136 pkt_type, hcmd);
137 return 0;
140 if (hlen > len) {
141 dbgprintf("pko_file: pko_accept_pkt: hdr->len is too large!! "
142 "(%d, can only receive %d)\n", hlen, len);
143 return 0;
146 // get the actual packet data
147 length = pko_recv_bytes(sock, buf + sizeof(pko_pkt_hdr),
148 hlen - sizeof(pko_pkt_hdr));
150 if (length < 0) {
151 dbgprintf("pko_file: accept recv2 error!!\n");
152 return 0;
155 if (length < (hlen - sizeof(pko_pkt_hdr))) {
156 dbgprintf("pko_accept_pkt: Did not receive full packet!!! "
157 "Fix this! (%d)\n", length);
160 return 1;
163 //----------------------------------------------------------------------
165 int pko_open_file(char *path, int flags)
167 pko_pkt_open_req *openreq;
168 pko_pkt_file_rly *openrly;
170 if (pko_fileio_sock < 0) {
171 return -1;
174 dbgprintf("pko_file: file open req (%s, %x)\n", path, flags);
176 openreq = (pko_pkt_open_req *)&send_packet[0];
178 // Build packet
179 openreq->cmd = htonl(PKO_OPEN_CMD);
180 openreq->len = htons((unsigned short)sizeof(pko_pkt_open_req));
181 openreq->flags = htonl(flags);
182 strncpy(openreq->path, path, PKO_MAX_PATH);
183 openreq->path[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated
185 if (pko_lwip_send(pko_fileio_sock, openreq, sizeof(pko_pkt_open_req), 0) < 0) {
186 return -1;
189 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
190 sizeof(pko_pkt_file_rly), PKO_OPEN_RLY)) {
191 dbgprintf("pko_file: pko_open_file: did not receive OPEN_RLY\n");
192 return -1;
195 openrly = (pko_pkt_file_rly *)recv_packet;
197 dbgprintf("pko_file: file open reply received (ret %d)\n", ntohl(openrly->retval));
199 return ntohl(openrly->retval);
203 //----------------------------------------------------------------------
205 int pko_close_file(int fd)
207 pko_pkt_close_req *closereq;
208 pko_pkt_file_rly *closerly;
211 if (pko_fileio_sock < 0) {
212 return -1;
215 dbgprintf("pko_file: file close req (fd: %d)\n", fd);
217 closereq = (pko_pkt_close_req *)&send_packet[0];
218 closerly = (pko_pkt_file_rly *)&recv_packet[0];
220 closereq->cmd = htonl(PKO_CLOSE_CMD);
221 closereq->len = htons((unsigned short)sizeof(pko_pkt_close_req));
222 closereq->fd = htonl(fd);
224 if (pko_lwip_send(pko_fileio_sock, closereq, sizeof(pko_pkt_close_req), 0) < 0) {
225 return -1;
228 if(!pko_accept_pkt(pko_fileio_sock, (char *)closerly,
229 sizeof(pko_pkt_file_rly), PKO_CLOSE_RLY)) {
230 dbgprintf("pko_file: pko_close_file: did not receive PKO_CLOSE_RLY\n");
231 return -1;
234 dbgprintf("pko_file: pko_close_file: close reply received (ret %d)\n",
235 ntohl(closerly->retval));
237 return ntohl(closerly->retval);
240 //----------------------------------------------------------------------
242 int pko_lseek_file(int fd, unsigned int offset, int whence)
244 pko_pkt_lseek_req *lseekreq;
245 pko_pkt_file_rly *lseekrly;
248 if (pko_fileio_sock < 0) {
249 return -1;
252 dbgprintf("pko_file: file lseek req (fd: %d)\n", fd);
254 lseekreq = (pko_pkt_lseek_req *)&send_packet[0];
255 lseekrly = (pko_pkt_file_rly *)&recv_packet[0];
257 lseekreq->cmd = htonl(PKO_LSEEK_CMD);
258 lseekreq->len = htons((unsigned short)sizeof(pko_pkt_lseek_req));
259 lseekreq->fd = htonl(fd);
260 lseekreq->offset = htonl(offset);
261 lseekreq->whence = htonl(whence);
263 if(pko_lwip_send(pko_fileio_sock, lseekreq, sizeof(pko_pkt_lseek_req), 0) < 0) {
264 return -1;
267 if(!pko_accept_pkt(pko_fileio_sock, (char *)lseekrly,
268 sizeof(pko_pkt_file_rly), PKO_LSEEK_RLY)) {
269 dbgprintf("pko_file: pko_lseek_file: did not receive PKO_LSEEK_RLY\n");
270 return -1;
273 dbgprintf("pko_file: pko_lseek_file: lseek reply received (ret %d)\n",
274 ntohl(lseekrly->retval));
276 return ntohl(lseekrly->retval);
281 //----------------------------------------------------------------------
283 int pko_write_file(int fd, char *buf, int length)
285 pko_pkt_write_req *writecmd;
286 pko_pkt_file_rly *writerly;
287 int hlen;
288 int writtenbytes;
289 int nbytes;
290 int retval;
292 if (pko_fileio_sock < 0) {
293 return -1;
296 dbgprintf("pko_file: file write req (fd: %d)\n", fd);
298 writecmd = (pko_pkt_write_req *)&send_packet[0];
299 writerly = (pko_pkt_file_rly *)&recv_packet[0];
301 hlen = (unsigned short)sizeof(pko_pkt_write_req);
302 writecmd->cmd = htonl(PKO_WRITE_CMD);
303 writecmd->len = htons(hlen);
304 writecmd->fd = htonl(fd);
306 // Divide the write request
307 writtenbytes = 0;
308 while (writtenbytes < length) {
310 if ((length - writtenbytes) > PKO_MAX_WRITE_SEGMENT) {
311 // Need to split in several read reqs
312 nbytes = PKO_MAX_READ_SEGMENT;
314 else {
315 nbytes = length - writtenbytes;
318 writecmd->nbytes = htonl(nbytes);
319 #ifdef ZEROCOPY
320 /* Send the packet header. */
321 if (pko_lwip_send(pko_fileio_sock, writecmd, hlen, 0) < 0)
322 return -1;
323 /* Send the write() data. */
324 if (pko_lwip_send(pko_fileio_sock, &buf[writtenbytes], nbytes, 0) < 0)
325 return -1;
326 #else
327 // Copy data to the acutal packet
328 memcpy(&send_packet[sizeof(pko_pkt_write_req)], &buf[writtenbytes],
329 nbytes);
331 if (pko_lwip_send(pko_fileio_sock, writecmd, hlen + nbytes, 0) < 0)
332 return -1;
333 #endif
336 // Get reply
337 if(!pko_accept_pkt(pko_fileio_sock, (char *)writerly,
338 sizeof(pko_pkt_file_rly), PKO_WRITE_RLY)) {
339 dbgprintf("pko_file: pko_write_file: "
340 "did not receive PKO_WRITE_RLY\n");
341 return -1;
343 retval = ntohl(writerly->retval);
345 dbgprintf("pko_file: wrote %d bytes (asked for %d)\n",
346 retval, nbytes);
348 if (retval < 0) {
349 // Error
350 dbgprintf("pko_file: pko_write_file: received error on write req (%d)\n",
351 retval);
352 return retval;
355 writtenbytes += retval;
356 if (retval < nbytes) {
357 // EOF?
358 break;
361 return writtenbytes;
364 //----------------------------------------------------------------------
366 int pko_read_file(int fd, char *buf, int length)
368 int readbytes;
369 int nbytes;
370 int i;
371 pko_pkt_read_req *readcmd;
372 pko_pkt_read_rly *readrly;
375 if (pko_fileio_sock < 0) {
376 return -1;
379 readcmd = (pko_pkt_read_req *)&send_packet[0];
380 readrly = (pko_pkt_read_rly *)&recv_packet[0];
381 readbytes = 0;
383 readcmd->cmd = htonl(PKO_READ_CMD);
384 readcmd->len = htons((unsigned short)sizeof(pko_pkt_read_req));
385 readcmd->fd = htonl(fd);
387 readbytes = 0;
389 if (length < 0) {
390 dbgprintf("pko_read_file: illegal req!! (whish to read < 0 bytes!)\n");
391 return -1;
394 readcmd->nbytes = htonl(length);
396 i = send(pko_fileio_sock, readcmd, sizeof(pko_pkt_read_req), 0);
397 if (i<0)
399 dbgprintf("pko_file: pko_read_file: send failed (%d)\n", i);
400 return -1;
403 if(!pko_accept_pkt(pko_fileio_sock, (char *)readrly,
404 sizeof(pko_pkt_read_rly), PKO_READ_RLY)) {
405 dbgprintf("pko_file: pko_read_file: "
406 "did not receive PKO_READ_RLY\n");
407 return -1;
410 nbytes = ntohl(readrly->nbytes);
411 dbgprintf("pko_file: pko_read_file: Reply said there's %d bytes to read "
412 "(wanted %d)\n", nbytes, length);
414 // Now read the actual file data
415 i = pko_recv_bytes(pko_fileio_sock, &buf[0], nbytes);
416 if (i < 0) {
417 dbgprintf("pko_file: pko_read_file, data read error\n");
418 return -1;
420 return nbytes;
421 return readbytes;
424 //----------------------------------------------------------------------
426 int pko_remove(char *name)
428 pko_pkt_remove_req *removereq;
429 pko_pkt_file_rly *removerly;
431 if (pko_fileio_sock < 0) {
432 return -1;
435 dbgprintf("pko_file: file remove req (%s)\n", name);
437 removereq = (pko_pkt_remove_req *)&send_packet[0];
439 // Build packet
440 removereq->cmd = htonl(PKO_REMOVE_CMD);
441 removereq->len = htons((unsigned short)sizeof(pko_pkt_remove_req));
442 strncpy(removereq->name, name, PKO_MAX_PATH);
443 removereq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated
445 if (pko_lwip_send(pko_fileio_sock, removereq, sizeof(pko_pkt_remove_req), 0) < 0) {
446 return -1;
449 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
450 sizeof(pko_pkt_file_rly), PKO_REMOVE_RLY)) {
451 dbgprintf("pko_file: pko_remove: did not receive REMOVE_RLY\n");
452 return -1;
455 removerly = (pko_pkt_file_rly *)recv_packet;
456 dbgprintf("pko_file: file remove reply received (ret %d)\n", ntohl(removerly->retval));
457 return ntohl(removerly->retval);
460 //----------------------------------------------------------------------
462 int pko_mkdir(char *name, int mode)
464 pko_pkt_mkdir_req *mkdirreq;
465 pko_pkt_file_rly *mkdirrly;
467 if (pko_fileio_sock < 0) {
468 return -1;
471 dbgprintf("pko_file: make dir req (%s)\n", name);
473 mkdirreq = (pko_pkt_mkdir_req *)&send_packet[0];
475 // Build packet
476 mkdirreq->cmd = htonl(PKO_MKDIR_CMD);
477 mkdirreq->len = htons((unsigned short)sizeof(pko_pkt_mkdir_req));
478 mkdirreq->mode = mode;
479 strncpy(mkdirreq->name, name, PKO_MAX_PATH);
480 mkdirreq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated
482 if (pko_lwip_send(pko_fileio_sock, mkdirreq, sizeof(pko_pkt_mkdir_req), 0) < 0) {
483 return -1;
486 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
487 sizeof(pko_pkt_file_rly), PKO_MKDIR_RLY)) {
488 dbgprintf("pko_file: pko_mkdir: did not receive MKDIR_RLY\n");
489 return -1;
492 mkdirrly = (pko_pkt_file_rly *)recv_packet;
493 dbgprintf("pko_file: make dir reply received (ret %d)\n", ntohl(mkdirrly->retval));
494 return ntohl(mkdirrly->retval);
497 //----------------------------------------------------------------------
499 int pko_rmdir(char *name)
501 pko_pkt_rmdir_req *rmdirreq;
502 pko_pkt_file_rly *rmdirrly;
504 if (pko_fileio_sock < 0) {
505 return -1;
508 dbgprintf("pko_file: remove dir req (%s)\n", name);
510 rmdirreq = (pko_pkt_rmdir_req *)&send_packet[0];
512 // Build packet
513 rmdirreq->cmd = htonl(PKO_RMDIR_CMD);
514 rmdirreq->len = htons((unsigned short)sizeof(pko_pkt_rmdir_req));
515 strncpy(rmdirreq->name, name, PKO_MAX_PATH);
516 rmdirreq->name[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated
518 if (pko_lwip_send(pko_fileio_sock, rmdirreq, sizeof(pko_pkt_rmdir_req), 0) < 0) {
519 return -1;
522 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
523 sizeof(pko_pkt_file_rly), PKO_RMDIR_RLY)) {
524 dbgprintf("pko_file: pko_rmdir: did not receive RMDIR_RLY\n");
525 return -1;
528 rmdirrly = (pko_pkt_file_rly *)recv_packet;
529 dbgprintf("pko_file: remove dir reply received (ret %d)\n", ntohl(rmdirrly->retval));
530 return ntohl(rmdirrly->retval);
533 //----------------------------------------------------------------------
535 int pko_open_dir(char *path)
537 pko_pkt_open_req *openreq;
538 pko_pkt_file_rly *openrly;
540 if (pko_fileio_sock < 0) {
541 return -1;
544 dbgprintf("pko_file: dir open req (%s)\n", path);
546 openreq = (pko_pkt_open_req *)&send_packet[0];
548 // Build packet
549 openreq->cmd = htonl(PKO_OPENDIR_CMD);
550 openreq->len = htons((unsigned short)sizeof(pko_pkt_open_req));
551 openreq->flags = htonl(0);
552 strncpy(openreq->path, path, PKO_MAX_PATH);
553 openreq->path[PKO_MAX_PATH - 1] = 0; // Make sure it's null-terminated
555 if (pko_lwip_send(pko_fileio_sock, openreq, sizeof(pko_pkt_open_req), 0) < 0) {
556 return -1;
559 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
560 sizeof(pko_pkt_file_rly), PKO_OPENDIR_RLY)) {
561 dbgprintf("pko_file: pko_open_dir: did not receive OPENDIR_RLY\n");
562 return -1;
565 openrly = (pko_pkt_file_rly *)recv_packet;
567 dbgprintf("pko_file: dir open reply received (ret %d)\n", ntohl(openrly->retval));
569 return ntohl(openrly->retval);
572 //----------------------------------------------------------------------
574 int pko_read_dir(int fd, void *buf)
576 pko_pkt_dread_req *dirreq;
577 pko_pkt_dread_rly *dirrly;
578 fio_dirent_t *dirent;
580 if (pko_fileio_sock < 0) {
581 return -1;
584 dbgprintf("pko_file: dir read req (%x)\n", fd);
586 dirreq = (pko_pkt_dread_req *)&send_packet[0];
588 // Build packet
589 dirreq->cmd = htonl(PKO_READDIR_CMD);
590 dirreq->len = htons((unsigned short)sizeof(pko_pkt_dread_req));
591 dirreq->fd = htonl(fd);
593 if (pko_lwip_send(pko_fileio_sock, dirreq, sizeof(pko_pkt_dread_req), 0) < 0) {
594 return -1;
597 if (!pko_accept_pkt(pko_fileio_sock, recv_packet,
598 sizeof(pko_pkt_dread_rly), PKO_READDIR_RLY)) {
599 dbgprintf("pko_file: pko_read_dir: did not receive OPENDIR_RLY\n");
600 return -1;
603 dirrly = (pko_pkt_dread_rly *)recv_packet;
605 dbgprintf("pko_file: dir read reply received (ret %d)\n", ntohl(dirrly->retval));
607 dirent = (fio_dirent_t *) buf;
608 // now handle the return buffer translation, to build reply bit
609 dirent->stat.mode = ntohl(dirrly->mode);
610 dirent->stat.attr = ntohl(dirrly->attr);
611 dirent->stat.size = ntohl(dirrly->size);
612 dirent->stat.hisize = ntohl(dirrly->hisize);
613 memcpy(dirent->stat.ctime,dirrly->ctime,8*3);
614 strncpy(dirent->name,dirrly->name,256);
615 dirent->unknown = 0;
617 return ntohl(dirrly->retval);
621 //----------------------------------------------------------------------
623 int pko_close_dir(int fd)
625 pko_pkt_close_req *closereq;
626 pko_pkt_file_rly *closerly;
629 if (pko_fileio_sock < 0) {
630 return -1;
633 dbgprintf("pko_file: dir close req (fd: %d)\n", fd);
635 closereq = (pko_pkt_close_req *)&send_packet[0];
636 closerly = (pko_pkt_file_rly *)&recv_packet[0];
638 closereq->cmd = htonl(PKO_CLOSEDIR_CMD);
639 closereq->len = htons((unsigned short)sizeof(pko_pkt_close_req));
640 closereq->fd = htonl(fd);
642 if (pko_lwip_send(pko_fileio_sock, closereq, sizeof(pko_pkt_close_req), 0) < 0) {
643 return -1;
646 if(!pko_accept_pkt(pko_fileio_sock, (char *)closerly,
647 sizeof(pko_pkt_file_rly), PKO_CLOSEDIR_RLY)) {
648 dbgprintf("pko_file: pko_close_dir: did not receive PKO_CLOSEDIR_RLY\n");
649 return -1;
652 dbgprintf("pko_file: dir close reply received (ret %d)\n",
653 ntohl(closerly->retval));
655 return ntohl(closerly->retval);
658 //----------------------------------------------------------------------
659 // Thread that waits for a PC to connect/disconnect/reconnect blah..
661 pko_file_serv(void *argv)
663 struct sockaddr_in server_addr;
664 struct sockaddr_in client_addr;
665 int sock;
666 int client_sock;
667 int client_len;
668 int ret;
670 dbgprintf(" - PS2 Side application -\n");
672 memset((void *)&server_addr, 0, sizeof(server_addr));
673 // Should perhaps specify PC side ip..
674 server_addr.sin_family = AF_INET;
675 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
676 server_addr.sin_port = htons(PKO_PORT);
678 while ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
679 dbgprintf("pko_file: socket creation error (%d)\n", sock);
680 return -1;
683 ret = bind(sock, (struct sockaddr *)&server_addr,
684 sizeof(server_addr));
685 if (ret < 0) {
686 dbgprintf("pko_file: bind error (%d)\n", ret);
687 disconnect(sock);
688 return -1;
691 ret = listen(sock, 5);
693 if (ret < 0) {
694 dbgprintf("pko_file: listen error (%d)\n", ret);
695 disconnect(sock);
696 return -1;
699 // Active flag kinda sux, cause it wont be checked until a new client has
700 // connected.. But it's better than nothing and good for now at least
701 pko_fileio_active = 1;
703 // Connection loop
704 while(pko_fileio_active)
706 dbgprintf("Waiting for connection\n");
708 client_len = sizeof(client_addr);
709 client_sock = accept(sock, (struct sockaddr *)&client_addr,
710 &client_len);
711 if (client_sock < 0) {
712 dbgprintf("pko_file: accept error (%d)", client_sock);
713 continue;
716 dbgprintf("Client connected from %x\n",
717 (int)client_addr.sin_addr.s_addr);
719 remote_pc_addr = client_addr.sin_addr.s_addr;
721 if (pko_fileio_sock > 0) {
722 dbgprintf("Client reconnected\n");
723 ret = disconnect(pko_fileio_sock);
724 dbgprintf("close ret %d\n", ret);
726 pko_fileio_sock = client_sock;
729 if (pko_fileio_sock > 0) {
730 disconnect(pko_fileio_sock);
733 disconnect(sock);
735 ExitDeleteThread();
736 return 0;