PS2SDK
PS2 Homebrew Libraries
ps2ip.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 <stdio.h>
17 #include <string.h>
18 #include <netman.h>
19 #include <lwip/memp.h>
20 
21 #include "lwip/sys.h"
22 #include "lwip/tcp.h"
23 #include "lwip/tcpip.h"
24 #include "lwip/netif.h"
25 #include "lwip/dhcp.h"
26 #include "lwip/prot/dhcp.h"
27 #include "lwip/inet.h"
28 #include "netif/etharp.h"
29 
30 #include "ps2ip_internal.h"
31 
32 typedef struct pbuf PBuf;
33 typedef struct netif NetIF;
34 typedef struct ip4_addr IPAddr;
35 
36 static struct netif NIF;
37 static struct pbuf *TxHead, *TxTail;
38 
39 int ps2ip_getconfig(char* pszName, t_ip_info* pInfo)
40 {
41  NetIF* pNetIF=netif_find(pszName);
42 
43  if (pNetIF==NULL)
44  {
45  //Net interface not found.
46  memset(pInfo,0,sizeof(*pInfo));
47  return 0;
48  }
49  strcpy(pInfo->netif_name,pszName);
50  pInfo->ipaddr.s_addr=pNetIF->ip_addr.addr;
51  pInfo->netmask.s_addr=pNetIF->netmask.addr;
52  pInfo->gw.s_addr=pNetIF->gw.addr;
53 
54  memcpy(pInfo->hw_addr,pNetIF->hwaddr,sizeof(pInfo->hw_addr));
55 
56 #if LWIP_DHCP
57  struct dhcp *dhcp = netif_dhcp_data(pNetIF);
58 
59  if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
60  {
61  pInfo->dhcp_enabled=1;
62  pInfo->dhcp_status=dhcp->state;
63  }
64  else
65  {
66  pInfo->dhcp_enabled=0;
67  pInfo->dhcp_status=DHCP_STATE_OFF;
68  }
69 
70 #else
71  pInfo->dhcp_enabled=0;
72 #endif
73 
74  return 1;
75 }
76 
77 int ps2ip_setconfig(const t_ip_info* pInfo)
78 {
79  NetIF* pNetIF=netif_find(pInfo->netif_name);
80 
81  if (pNetIF==NULL)
82  {
83  return 0;
84  }
85 
86 #if LWIP_DHCP
87  struct dhcp *dhcp = netif_dhcp_data(pNetIF);
88 
89  //Enable dhcp here
90 
91  if (pInfo->dhcp_enabled)
92  {
93  if ((dhcp == NULL) || (dhcp->state == DHCP_STATE_OFF))
94  {
95  //Set initial IP address
96  netif_set_ipaddr(pNetIF,(IPAddr*)&pInfo->ipaddr);
97  netif_set_netmask(pNetIF,(IPAddr*)&pInfo->netmask);
98  netif_set_gw(pNetIF,(IPAddr*)&pInfo->gw);
99 
100  //Start DHCP client
101  dhcp_start(pNetIF);
102  }
103  }
104  else
105  {
106  if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF))
107  {
108  //Release DHCP lease
109  dhcp_release(pNetIF);
110 
111  //Stop DHCP client
112  dhcp_stop(pNetIF);
113  }
114 
115  netif_set_ipaddr(pNetIF,(IPAddr*)&pInfo->ipaddr);
116  netif_set_netmask(pNetIF,(IPAddr*)&pInfo->netmask);
117  netif_set_gw(pNetIF,(IPAddr*)&pInfo->gw);
118  }
119 
120 #else
121  netif_set_ipaddr(pNetIF,(IPAddr*)&pInfo->ipaddr);
122  netif_set_netmask(pNetIF,(IPAddr*)&pInfo->netmask);
123  netif_set_gw(pNetIF,(IPAddr*)&pInfo->gw);
124 #endif
125 
126  return 1;
127 }
128 
129 static void EnQTxPacket(struct pbuf *tx)
130 {
131  DI();
132 
133  if(TxHead != NULL)
134  TxHead->next = tx;
135 
136  TxHead = tx;
137  tx->next = NULL;
138 
139  if(TxTail == NULL) //Queue empty
140  TxTail = tx;
141 
142  EI();
143 }
144 
145 static err_t SMapLowLevelOutput(struct netif* pNetIF, struct pbuf* pOutput)
146 {
147  err_t result;
148 
149  (void)pNetIF;
150 
151  result = ERR_OK;
152  if(pOutput->tot_len > pOutput->len)
153  {
154  struct pbuf* pbuf;
155 
156  pbuf_ref(pOutput); //Increment reference count because LWIP must free the PBUF, not the driver!
157  if((pbuf = pbuf_coalesce(pOutput, PBUF_RAW)) != pOutput)
158  { //No need to increase reference count because pbuf_coalesce() does it.
159  EnQTxPacket(pbuf);
160  NetManNetIFXmit();
161  } else
162  result = ERR_MEM;
163  } else {
164  pbuf_ref(pOutput); //This will be freed later.
165  EnQTxPacket(pOutput);
166  NetManNetIFXmit();
167  }
168 
169  return result;
170 }
171 
172 static void LinkStateUp(void)
173 {
174  tcpip_callback((void*)&netif_set_link_up, &NIF);
175 }
176 
177 static void LinkStateDown(void)
178 {
179  tcpip_callback((void*)&netif_set_link_down, &NIF);
180 }
181 
182 static void *AllocRxPacket(unsigned int size, void **payload)
183 {
184  struct pbuf* pbuf;
185 
186  if((pbuf = pbuf_alloc(PBUF_RAW, size, PBUF_POOL)) != NULL)
187  *payload = pbuf->payload;
188 
189  return pbuf;
190 }
191 
192 static void ReallocRxPacket(void *packet, unsigned int size)
193 {
194  pbuf_realloc((struct pbuf *)packet, size);
195 }
196 
197 static void FreeRxPacket(void *packet)
198 {
199  pbuf_free(packet);
200 }
201 
202 static void EnQRxPacket(void *packet)
203 {
204  ps2ip_input(packet, &NIF);
205 }
206 
207 static int NextTxPacket(void **payload)
208 {
209  int len;
210 
211  if(TxTail != NULL)
212  {
213  *payload = TxTail->payload;
214  len = TxTail->len;
215  } else
216  len = 0;
217 
218  return len;
219 }
220 
221 static void DeQTxPacket(void)
222 {
223  struct pbuf *toFree;
224 
225  toFree = NULL;
226 
227  DI();
228  if(TxTail != NULL)
229  {
230  toFree = TxTail;
231 
232  if(TxTail == TxHead) {
233  //Last in queue.
234  TxTail = NULL;
235  TxHead = NULL;
236  } else {
237  TxTail = TxTail->next;
238  }
239  }
240  EI();
241 
242  if(toFree != NULL)
243  {
244  toFree->next = NULL;
245  pbuf_free(toFree);
246  }
247 }
248 
249 static int AfterTxPacket(void **payload)
250 {
251  int len;
252 
253  if(TxTail != NULL && TxTail->next != NULL)
254  {
255  *payload = TxTail->next->payload;
256  len = TxTail->next->len;
257  } else
258  len = 0;
259 
260  return len;
261 }
262 
263 static void InitDone(void* pvArg)
264 {
265  dbgprintf("InitDone: TCPIP initialized\n");
266  sys_sem_signal((sys_sem_t*)pvArg);
267 }
268 
270 static err_t SMapIFInit(struct netif* pNetIF)
271 {
272  TxHead = NULL;
273  TxTail = NULL;
274 
275  pNetIF->name[0]='s';
276  pNetIF->name[1]='m';
277  pNetIF->output=&etharp_output; // For LWIP 1.3.0 and later.
278  pNetIF->linkoutput=&SMapLowLevelOutput;
280  pNetIF->flags|=(NETIF_FLAG_ETHARP|NETIF_FLAG_BROADCAST); // For LWIP v1.3.0 and later.
281  pNetIF->mtu=1500;
282 
283  //Get MAC address.
284  NetManIoctl(NETMAN_NETIF_IOCTL_ETH_GET_MAC, NULL, 0, pNetIF->hwaddr, sizeof(pNetIF->hwaddr));
285  dbgprintf("MAC address : %02d:%02d:%02d:%02d:%02d:%02d\n",pNetIF->hwaddr[0],pNetIF->hwaddr[1],pNetIF->hwaddr[2],
286  pNetIF->hwaddr[3],pNetIF->hwaddr[4],pNetIF->hwaddr[5]);
287 
288  return ERR_OK;
289 }
290 
291 err_t ps2ip_input(PBuf* pInput, NetIF* pNetIF)
292 {
293  err_t result;
294 
295  if((result = pNetIF->input(pInput, pNetIF)) != ERR_OK)
296  pbuf_free(pInput);
297 
298  return result;
299 }
300 
301 static inline void InitializeLWIP(void)
302 {
303  sys_sem_t Sema;
304 
305  dbgprintf("PS2IP: Module Loaded.\n");
306 
307  sys_sem_new(&Sema, 0);
308  dbgprintf("PS2IP: Calling tcpip_init\n");
309  tcpip_init(InitDone,&Sema);
310 
311  sys_arch_sem_wait(&Sema, 0);
312  sys_sem_free(&Sema);
313 
314  dbgprintf("PS2IP: System Initialised\n");
315 }
316 
317 /* The following are defined in ps2ip_ps2sdk.c */
318 extern void _ps2sdk_ps2ipee_init(void);
319 extern void _ps2sdk_ps2ipee_deinit(void);
320 
321 int ps2ipInit(struct ip4_addr *ip_address, struct ip4_addr *subnet_mask, struct ip4_addr *gateway){
322  static const struct NetManNetProtStack stack={
323  &LinkStateUp,
324  &LinkStateDown,
325  &AllocRxPacket,
326  &FreeRxPacket,
327  &EnQRxPacket,
328  &NextTxPacket,
329  &DeQTxPacket,
330  &AfterTxPacket,
331  &ReallocRxPacket
332  };
333 
334  NetManInit();
335 
336  InitializeLWIP();
337 
338  netif_add(&NIF, ip_address, subnet_mask, gateway, NULL, &SMapIFInit, tcpip_input);
339  netif_set_default(&NIF);
340 
341  NetManRegisterNetworkStack(&stack);
342  netif_set_up(&NIF);
343 
344  _ps2sdk_ps2ipee_init();
345 
346  return 0;
347 }
348 
349 void ps2ipDeinit(void){
350  _ps2sdk_ps2ipee_deinit();
351 
352  NetManUnregisterNetworkStack();
353 }
354 
355 // Stubbed for compatibility purposes
356 void ps2ipSetHsyncTicksPerMSec(unsigned char ticks) {}
PBUF_POOL
@ PBUF_POOL
Definition: tcpip.h:225
netif::output
netif_output_fn output
Definition: tcpip.h:1288
NetManNetProtStack
Definition: netman.h:16
netif::hwaddr
u8 hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: tcpip.h:1341
PBUF_RAW
@ PBUF_RAW
Definition: tcpip.h:196
NETIF_FLAG_ETHARP
#define NETIF_FLAG_ETHARP
Definition: tcpip.h:1129
NETIF_MAX_HWADDR_LEN
#define NETIF_MAX_HWADDR_LEN
Definition: tcpip.h:1101
netif_find
struct netif * netif_find(const char *name)
netif::hwaddr_len
u8 hwaddr_len
Definition: tcpip.h:1339
t_ip_info
Definition: tcpip.h:1990
ps2ipSetHsyncTicksPerMSec
void ps2ipSetHsyncTicksPerMSec(unsigned char ticks)
Definition: ps2ip.c:356
netman.h
netif::name
char name[2]
Definition: tcpip.h:1345
SMapIFInit
static err_t SMapIFInit(struct netif *pNetIF)
Definition: ps2ip.c:270
netif::input
netif_input_fn input
Definition: tcpip.h:1282
pbuf::tot_len
u16 tot_len
Definition: tcpip.h:244
ip4_addr
Definition: tcpip.h:266
stdio.h
netif::linkoutput
netif_linkoutput_fn linkoutput
Definition: tcpip.h:1293
pbuf::next
struct pbuf * next
Definition: tcpip.h:232
netif
Definition: tcpip.h:1262
NETMAN_NETIF_IOCTL_ETH_GET_MAC
@ NETMAN_NETIF_IOCTL_ETH_GET_MAC
Definition: netman.h:78
NetManIoctl
Definition: netman_rpc.h:60
netif::flags
u8 flags
Definition: tcpip.h:1343
ps2ipInit
int ps2ipInit(struct ip4_addr *ip_address, struct ip4_addr *subnet_mask, struct ip4_addr *gateway)
Definition: ps2ip.c:321
pbuf
Definition: tcpip.h:229
pbuf::len
u16 len
Definition: tcpip.h:247
netif::ip_addr
ip_addr_t ip_addr
Definition: tcpip.h:1269
netif::mtu
u16 mtu
Definition: tcpip.h:1337
NETIF_FLAG_BROADCAST
#define NETIF_FLAG_BROADCAST
Definition: tcpip.h:1119
pbuf::payload
void * payload
Definition: tcpip.h:235