Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / wip / lanman / arp.c
blob5a93bb510e5eb74dad3b5f1ee07a7f4ad9262cdb
1 /*
2 Copyright (c) 2010 jimmikaelkael <jimmikaelkael@wanadoo.fr>
3 Licenced under Academic Free License version 3.0
4 */
6 #include <tamtypes.h>
7 #include <stdio.h>
8 #include <intrman.h>
9 #include <thbase.h>
10 #include <thsemap.h>
11 #include <errno.h>
13 #include "arp.h"
14 #include "smsutils.h"
15 #include "smap.h"
16 #include "inet.h"
18 static g_param_t *g_param;
20 // ARP
22 static int arp_mutex = -1;
23 static int arp_reply_flag;
24 static int wait_arp_reply = 0;
26 //-------------------------------------------------------------------------
27 void arp_init(g_param_t *gparam)
29 g_param = gparam;
31 arp_request();
34 //-------------------------------------------------------------------------
35 static void arp_output(u16 opcode, u8 *target_eth_addr)
37 arp_pkt_t arp_pkt;
39 mips_memset(&arp_pkt, 0, sizeof(arp_pkt_t));
40 mips_memcpy(arp_pkt.eth.addr_dst, g_param->eth_addr_dst, 12);
41 arp_pkt.eth.type = 0x0608; // Network byte order: 0x806
43 arp_pkt.arp_hwtype = 0x0100; // Network byte order: 0x01
44 arp_pkt.arp_protocoltype = 0x0008; // Network byte order: 0x800
45 arp_pkt.arp_hwsize = 6;
46 arp_pkt.arp_protocolsize = 4;
47 arp_pkt.arp_opcode = htons(opcode);
48 mips_memcpy(arp_pkt.arp_sender_eth_addr, g_param->eth_addr_src, 6);
49 mips_memcpy(&arp_pkt.arp_sender_ip_addr, &g_param->ip_addr_src, 4);
50 mips_memcpy(arp_pkt.arp_target_eth_addr, target_eth_addr, 6);
51 mips_memcpy(&arp_pkt.arp_target_ip_addr, &g_param->ip_addr_dst, 4);
53 while (smap_xmit(&arp_pkt, sizeof(arp_pkt_t)) != 0);
56 //-------------------------------------------------------------------------
57 void arp_input(void *buf, int size) // !!! Intr Context !!!
59 arp_pkt_t *arp_pkt = (arp_pkt_t *)buf;
61 if (arp_pkt->arp_opcode == 0x0200) { // checking for ARP reply - network byte order
63 if (wait_arp_reply) {
64 mips_memcpy(g_param->eth_addr_dst, &arp_pkt->arp_sender_eth_addr[0], 6);
66 arp_reply_flag = 1;
67 iSignalSema(arp_mutex);
69 } else if (arp_pkt->arp_opcode == 0x0100) { // checking for ARP request - network byte order
70 int i;
71 for (i=0; i<4; i++) {
72 u8 *p = (u8 *)&g_param->ip_addr_src;
73 if (arp_pkt->arp_target_ip_addr.addr[i] != p[i])
74 break;
76 if (i == 4)
77 arp_output(ARP_REPLY, g_param->eth_addr_dst);
81 //-------------------------------------------------------------------------
82 static unsigned int timer_intr_handler(void *args)
84 iSignalSema(arp_mutex);
86 return (unsigned int)args;
89 //-------------------------------------------------------------------------
90 void arp_request(void)
92 iop_sys_clock_t sysclock;
93 int oldstate;
95 arp_mutex = CreateMutex(IOP_MUTEX_LOCKED);
97 CpuSuspendIntr(&oldstate);
98 wait_arp_reply = 1;
99 CpuResumeIntr(oldstate);
101 send_arp_request:
103 // Send an ARP resquest
104 arp_output(ARP_REQUEST, "\x00\x00\x00\x00\x00\x00");
106 USec2SysClock(3000*1000, &sysclock);
107 SetAlarm(&sysclock, timer_intr_handler, NULL);
109 // Wait for ARP reply or timeout
110 WaitSema(arp_mutex);
112 //while (QueryIntrContext())
113 // DelayThread(10000);
115 CpuSuspendIntr(&oldstate);
116 CancelAlarm(timer_intr_handler, NULL);
117 if (arp_reply_flag == 0) { // It was a timeout ?
118 CpuResumeIntr(oldstate);
119 goto send_arp_request; // yes, retry...
121 wait_arp_reply = 0;
122 arp_reply_flag = 0;
123 CpuResumeIntr(oldstate);
125 DeleteSema(arp_mutex);
126 arp_mutex = -1;