PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
main.c
1#ifdef BUILDING_SMAP_NETMAN
2#include <errno.h>
3#endif
4#include <stdio.h>
5#include <defs.h>
6#ifdef BUILDING_SMAP_PS2IP
7#include <sysclib.h>
8#endif
9#include <loadcore.h>
10#include <thbase.h>
11#ifdef BUILDING_SMAP_PS2IP
12#include <thevent.h>
13#include <thsemap.h>
14#include <intrman.h>
15#endif
16#ifdef BUILDING_SMAP_PS2IP
17#include <ps2ip.h>
18#endif
19#ifdef BUILDING_SMAP_NETMAN
20#include <irx.h>
21#include <netman.h>
22#endif
23
24#include "main.h"
25#ifdef BUILDING_SMAP_NETMAN
26#include "xfer.h"
27#endif
28
29// Last SDK 3.1.0 has INET family version "2.26.0"
30// SMAP module is the same as "2.25.0"
31IRX_ID("SMAP_driver", 0x2, 0x1A);
32
33#ifdef BUILDING_SMAP_PS2IP
34
35#define IFNAME0 's'
36#define IFNAME1 'm'
37
38typedef struct ip4_addr IPAddr;
39typedef struct netif NetIF;
40typedef struct SMapIF SMapIF;
41typedef struct pbuf PBuf;
42
43static struct pbuf *TxHead, *TxTail;
44static void EnQTxPacket(struct pbuf *tx);
45
46static NetIF NIF;
47
48// From lwip/err.h and lwip/tcpip.h
49
50#define ERR_OK 0 // No error, everything OK
51#define ERR_MEM -1 // Out of memory error.
52#define ERR_CONN -6 // Not connected
53#define ERR_IF -11 // Low-level netif error
54
55// SMapLowLevelOutput():
56
57// This function is called by the TCP/IP stack when a low-level packet should be sent. It'll be invoked in the context of the
58// tcpip-thread.
59
60static err_t
61SMapLowLevelOutput(NetIF *pNetIF, PBuf *pOutput)
62{
63 err_t result;
64 struct pbuf *pbuf;
65
66#if USE_GP_REGISTER
67 void *OldGP;
68
69 OldGP = SetModuleGP();
70#endif
71
72 (void)pNetIF;
73
74 result = ERR_OK;
75 if (pOutput->tot_len > pOutput->len) {
76 pbuf_ref(pOutput); // Increment reference count because LWIP must free the PBUF, not the driver!
77 if ((pbuf = pbuf_coalesce(pOutput, PBUF_RAW)) != pOutput) { // No need to increase reference count because pbuf_coalesce() does it.
78 EnQTxPacket(pbuf);
79 SMAPXmit();
80 } else
81 result = ERR_MEM;
82 } else {
83 pbuf_ref(pOutput); // This will be freed later.
84 EnQTxPacket(pOutput);
85 SMAPXmit();
86 }
87
88#if USE_GP_REGISTER
89 SetGP(OldGP);
90#endif
91
92 return result;
93}
94
95// SMapOutput():
96
97// This function is called by the TCP/IP stack when an IP packet should be sent. It'll be invoked in the context of the
98// tcpip-thread, hence no synchronization is required.
99// For LWIP versions before v1.3.0.
100#ifdef PRE_LWIP_130_COMPAT
101static err_t
102SMapOutput(NetIF *pNetIF, PBuf *pOutput, IPAddr *pIPAddr)
103{
104 err_t result;
105 PBuf *pBuf;
106
107#if USE_GP_REGISTER
108 void *OldGP;
109
110 OldGP = SetModuleGP();
111#endif
112
113 pBuf = etharp_output(pNetIF, pIPAddr, pOutput);
114
115 result = pBuf != NULL ? SMapLowLevelOutput(pNetIF, pBuf) : ERR_OK;
116
117#if USE_GP_REGISTER
118 SetGP(OldGP);
119#endif
120
121 return result;
122}
123#endif
124
125// SMapIFInit():
126
127// Should be called at the beginning of the program to set up the network interface.
128
129static err_t
130SMapIFInit(NetIF *pNetIF)
131{
132#if USE_GP_REGISTER
133 void *OldGP;
134
135 OldGP = SetModuleGP();
136#endif
137
138 TxHead = NULL;
139 TxTail = NULL;
140
141 pNetIF->name[0] = IFNAME0;
142 pNetIF->name[1] = IFNAME1;
143#ifdef PRE_LWIP_130_COMPAT
144 pNetIF->output = &SMapOutput; // For LWIP versions before v1.3.0.
145#else
146 pNetIF->output = &etharp_output; // For LWIP 1.3.0 and later.
147#endif
148 pNetIF->linkoutput = &SMapLowLevelOutput;
150#ifdef PRE_LWIP_130_COMPAT
151 pNetIF->flags |= (NETIF_FLAG_LINK_UP | NETIF_FLAG_BROADCAST); // For LWIP versions before v1.3.0.
152#else
153 pNetIF->flags |= (NETIF_FLAG_ETHARP | NETIF_FLAG_BROADCAST); // For LWIP v1.3.0 and later.
154#endif
155 pNetIF->mtu = 1500;
156
157 // Get MAC address.
158 SMAPGetMACAddress(pNetIF->hwaddr);
159 DEBUG_PRINTF("MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n", pNetIF->hwaddr[0], pNetIF->hwaddr[1], pNetIF->hwaddr[2],
160 pNetIF->hwaddr[3], pNetIF->hwaddr[4], pNetIF->hwaddr[5]);
161
162 // Enable sending and receiving of data.
163 SMAPInitStart();
164
165#if USE_GP_REGISTER
166 SetGP(OldGP);
167#endif
168
169 return ERR_OK;
170}
171
172void SMapLowLevelInput(PBuf *pBuf)
173{
174 // When we receive data, the interrupt-handler will invoke this function, which means we are in an interrupt-context. Pass on
175 // the received data to ps2ip.
176
177 ps2ip_input(pBuf, &NIF);
178}
179
180static void EnQTxPacket(struct pbuf *tx)
181{
182 int OldState;
183
184 CpuSuspendIntr(&OldState);
185
186 if (TxHead != NULL)
187 TxHead->next = tx;
188
189 TxHead = tx;
190 tx->next = NULL;
191
192 if (TxTail == NULL) // Queue empty
193 TxTail = TxHead;
194
195 CpuResumeIntr(OldState);
196}
197
198int SMapTxPacketNext(void **payload)
199{
200 int len;
201
202 if (TxTail != NULL) {
203 *payload = TxTail->payload;
204 len = TxTail->len;
205 } else
206 len = 0;
207
208 return len;
209}
210
211void SMapTxPacketDeQ(void)
212{
213 struct pbuf *toFree;
214 int OldState;
215
216 toFree = NULL;
217
218 CpuSuspendIntr(&OldState);
219 if (TxTail != NULL) {
220 toFree = TxTail;
221
222 if (TxTail == TxHead) {
223 // Last in queue.
224 TxTail = NULL;
225 TxHead = NULL;
226 } else {
227 TxTail = TxTail->next;
228 }
229 }
230 CpuResumeIntr(OldState);
231
232 if (toFree != NULL) {
233 toFree->next = NULL;
234 pbuf_free(toFree);
235 }
236}
237
238static inline int SMapInit(IPAddr *IP, IPAddr *NM, IPAddr *GW, int argc, char *argv[])
239{
240 if (smap_init(argc, argv) != 0) {
241 return 0;
242 }
243 DEBUG_PRINTF("SMapInit: SMap initialized\n");
244
245 netif_add(&NIF, IP, NM, GW, &NIF, &SMapIFInit, tcpip_input);
246 netif_set_default(&NIF);
247 netif_set_up(&NIF);
248 DEBUG_PRINTF("SMapInit: NetIF added to ps2ip\n");
249
250 // Return 1 (true) to indicate success.
251
252 return 1;
253}
254
255static void
256PrintIP(struct ip4_addr const *pAddr)
257{
258 printf("%d.%d.%d.%d", (u8)pAddr->addr, (u8)(pAddr->addr >> 8), (u8)(pAddr->addr >> 16), (u8)(pAddr->addr >> 24));
259}
260
261void PS2IPLinkStateUp(void)
262{
263 tcpip_callback((void *)&netif_set_link_up, &NIF);
264}
265
266void PS2IPLinkStateDown(void)
267{
268 tcpip_callback((void *)&netif_set_link_down, &NIF);
269}
270#endif
271
272#ifdef BUILDING_SMAP_NETMAN
273// While the header of the export table is small, the large size of the export table (as a whole) places it in data instead of sdata.
274extern struct irx_export_table _exp_smap __attribute__((section("data")));
275#endif
276
277#ifdef BUILDING_SMAP_MODULAR
278extern struct irx_export_table _exp_smapmodu __attribute__((section("data")));
279#endif
280
281int _start(int argc, char *argv[])
282{
283#ifdef BUILDING_SMAP_PS2IP
284 IPAddr IP;
285 IPAddr NM;
286 IPAddr GW;
287 int numArgs;
288 char **pArgv;
289#endif
290#ifdef BUILDING_SMAP_NETMAN
291 int result;
292#endif
293
294#ifdef BUILDING_SMAP_NETMAN
295 if (RegisterLibraryEntries(&_exp_smap) != 0) {
296 DEBUG_PRINTF("module already loaded\n");
297 return MODULE_NO_RESIDENT_END;
298 }
299#endif
300
301#ifdef BUILDING_SMAP_MODULAR
302 if (RegisterLibraryEntries(&_exp_smapmodu) != 0) {
303 DEBUG_PRINTF("module already loaded\n");
304 return MODULE_NO_RESIDENT_END;
305 }
306#endif
307
308 DisplayBanner();
309
310 // This code was present in SMAP, but cannot be implemented with the default IOP kernel due to MODLOAD missing these functions.
311 // It may be necessary to prevent SMAP from linking with an old DEV9 module.
312
313 /* if ((ModuleID = SearchModuleByName("dev9")) < 0) {
314 sceInetPrintf("dev9 module not found\n");
315 return MODULE_NO_RESIDENT_END;
316 }
317 if (ReferModuleStatus(ModuleID, &ModStatus) < 0) {
318 sceInetPrintf("can't get dev9 module status\n");
319 return MODULE_NO_RESIDENT_END;
320 }
321
322 if (ModStatus.version < 0x204) {
323 sceInetPrintf("dev9 module version must be 2.4 or later\n");
324 return MODULE_NO_RESIDENT_END;
325 } */
326
327#ifdef BUILDING_SMAP_PS2IP
328 // Parse IP args.
329 DEBUG_PRINTF("argc %d\n", argc);
330
331 if (argc >= 4) {
332 DEBUG_PRINTF("%s %s %s\n", argv[1], argv[2], argv[3]);
333 IP.addr = inet_addr(argv[1]);
334 NM.addr = inet_addr(argv[2]);
335 GW.addr = inet_addr(argv[3]);
336
337 numArgs = argc - 4;
338 pArgv = &argv[4];
339 } else {
340 // Set some defaults.
341
342 IP4_ADDR(&IP, 192, 168, 0, 80);
343 IP4_ADDR(&NM, 255, 255, 255, 0);
344 IP4_ADDR(&GW, 192, 168, 0, 1);
345
346 numArgs = argc - 1;
347 pArgv = &argv[1];
348 }
349#endif
350
351#ifdef BUILDING_SMAP_NETMAN
352 if ((result = smap_init(argc, argv)) < 0) {
353 DEBUG_PRINTF("smap_init -> %d\n", result);
354 ReleaseLibraryEntries(&_exp_smap);
355 return MODULE_NO_RESIDENT_END;
356 }
357#endif
358
359#ifdef BUILDING_SMAP_PS2IP
360 if (!SMapInit(&IP, &NM, &GW, numArgs, pArgv)) {
361
362 // Something went wrong, return 1 to indicate failure.
363 return MODULE_NO_RESIDENT_END;
364 }
365
366 printf("Initialized OK, IP: ");
367 PrintIP(&IP);
368 printf(", NM: ");
369 PrintIP(&NM);
370 printf(", GW: ");
371 PrintIP(&GW);
372 printf("\n");
373
374 // Initialized ok.
375#endif
376
377 return MODULE_RESIDENT_END;
378}
static err_t SMapIFInit(struct netif *pNetIF)
Definition ps2ip.c:272
#define NETIF_FLAG_LINK_UP
Definition tcpip.h:1095
#define NETIF_FLAG_ETHARP
Definition tcpip.h:1099
#define NETIF_FLAG_BROADCAST
Definition tcpip.h:1089
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
#define tcpip_callback(f, ctx)
Definition ps2ip.h:70
char name[2]
Definition tcpip.h:1315
u8 hwaddr_len
Definition tcpip.h:1309
#define IP4_ADDR(ipaddr, a, b, c, d)
Definition tcpip.h:290
struct pbuf * next
Definition tcpip.h:202
void * payload
Definition tcpip.h:205
netif_output_fn output
Definition tcpip.h:1258
#define NETIF_MAX_HWADDR_LEN
Definition tcpip.h:1071
u16 tot_len
Definition tcpip.h:214
u8 hwaddr[NETIF_MAX_HWADDR_LEN]
Definition tcpip.h:1311
u8 flags
Definition tcpip.h:1313
netif_linkoutput_fn linkoutput
Definition tcpip.h:1263
u16 len
Definition tcpip.h:217
@ PBUF_RAW
Definition tcpip.h:166
u16 mtu
Definition tcpip.h:1307
Definition tcpip.h:200