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