PS2SDK
PS2 Homebrew Libraries
rpc_server.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <sysclib.h>
4 #include <sifcmd.h>
5 #include <sifman.h>
6 #include <loadcore.h>
7 #include <thbase.h>
8 #include <thevent.h>
9 #include <thsemap.h>
10 #include <intrman.h>
11 #include <netman.h>
12 #include <netman_rpc.h>
13 
14 #include "internal.h"
15 #include "rpc_server.h"
16 #include "rpc_client.h"
17 
18 /* Data used for registering the RPC server. */
19 static SifRpcServerData_t rpc_sdata;
20 static unsigned char rpc_buffer[80] __attribute__((__aligned__(4)));
21 static SifRpcDataQueue_t rpc_qdata;
22 
23 static union{
24  s32 result;
25  struct NetManIoctlResult IoctlResult;
26  struct NetManQueryMainNetIFResult QueryMainNetIFResult;
27  struct NetManRegNetworkStackResult RegNetworkStackResult;
28  u8 buffer[80];
29 } SifRpcTxBuffer;
30 
31 /* Packet transmission buffer. The EE will DMA transfer the packet to be transmitted directly into this buffer before invoking FUNC_SEND_PACKET. */
32 static u8 *TxFrameBuffer = NULL;
33 static struct NetManBD *FrameBufferStatus = NULL;
34 static struct NetManBD *EEFrameBufferStatus = NULL;
35 static unsigned short int IOPFrameBufferRdPtr;
36 
37 static int RpcThreadID = -1;
38 static unsigned char IsInitialized=0, IsRpcStackInitialized=0;
39 
40 static void ClearBufferLen(int index);
41 
42 static void LinkStateUp(void)
43 {
44  NetManRpcToggleGlobalNetIFLinkState(1);
45 }
46 
47 static void LinkStateDown(void)
48 {
49  NetManRpcToggleGlobalNetIFLinkState(0);
50 }
51 
52 static void *AllocRxPacket(unsigned int length, void **payload)
53 {
54  return NetManRpcNetProtStackAllocRxPacket(length, payload);
55 }
56 
57 static void FreeRxPacket(void *packet)
58 {
59  NetManRpcNetProtStackFreeRxPacket(packet);
60 }
61 
62 static void EnQRxPacket(void *packet)
63 {
64  NetManRpcProtStackEnQRxPacket(packet);
65 }
66 
67 static int NextTxPacket(void **payload)
68 {
69  *payload = &TxFrameBuffer[IOPFrameBufferRdPtr * NETMAN_MAX_FRAME_SIZE + FrameBufferStatus[IOPFrameBufferRdPtr].offset];
70  return FrameBufferStatus[IOPFrameBufferRdPtr].length;
71 }
72 
73 static void DeQTxPacket(void)
74 {
75  ClearBufferLen(IOPFrameBufferRdPtr);
76 
77  //Increment read pointer by one place.
78  IOPFrameBufferRdPtr = (IOPFrameBufferRdPtr + 1) % NETMAN_RPC_BLOCK_SIZE;
79 }
80 
81 static struct NetManNetProtStack RpcStack={
82  &LinkStateUp,
83  &LinkStateDown,
84  &AllocRxPacket,
85  &FreeRxPacket,
86  &EnQRxPacket,
87  &NextTxPacket,
88  &DeQTxPacket,
89  NULL,
90  NULL,
91 };
92 
93 static void unregisterEENetworkStack(void)
94 {
95  if(IsRpcStackInitialized)
96  {
97  IsRpcStackInitialized=0;
98  NetManUnregisterNetworkStack();
99 
100  if(TxFrameBuffer != NULL)
101  {
102  free(TxFrameBuffer);
103  TxFrameBuffer = NULL;
104  }
105  if(FrameBufferStatus != NULL)
106  {
107  free(FrameBufferStatus);
108  FrameBufferStatus = NULL;
109  }
110 
111  EEFrameBufferStatus = NULL;
112  }
113 
114  sceSifRemoveCmdHandler(NETMAN_SIFCMD_ID);
115 }
116 
117 static void ClearBufferLen(int index)
118 {
119  static struct NetManBD zero = { 0 };
120  SifDmaTransfer_t dmat;
121  int dmat_id, OldState;
122 
123  FrameBufferStatus[index].length = 0;
124 
125  //Transfer to EE RAM
126  dmat.src = (void*)&zero;
127  dmat.dest = &EEFrameBufferStatus[index];
128  dmat.size = sizeof(zero);
129  dmat.attr = 0;
130 
131  do{
132  CpuSuspendIntr(&OldState);
133  dmat_id = sceSifSetDma(&dmat, 1);
134  CpuResumeIntr(OldState);
135  }while(dmat_id == 0);
136 }
137 
138 static void HandleRxEvent(void *packet, void *common)
139 {
140  struct NetManPktCmd *bd = (struct NetManPktCmd*)&((SifCmdHeader_t*)packet)->opt;
141  u8 id = bd->id;
142  u8 offset = bd->offset;
143  u16 len = bd->length;
144 
145  (void)common;
146 
147  FrameBufferStatus[id].length = len;
148  FrameBufferStatus[id].offset = offset;
149 
150  NetManNetIFXmit();
151 }
152 
153 static void *NETMAN_rpc_handler(int fno, void *buffer, int size)
154 {
155  static int ResultValue;
156  void *result;
157 
158  (void)size;
159 
160  switch(fno)
161  {
162  case NETMAN_IOP_RPC_FUNC_INIT:
163  ResultValue=NetManInitRPCClient();
164  result=&ResultValue;
165  break;
166  case NETMAN_IOP_RPC_FUNC_DEINIT:
167  unregisterEENetworkStack();
168  NetManDeinitRPCClient();
169  result=NULL;
170  break;
171  case NETMAN_IOP_RPC_FUNC_REG_NETWORK_STACK:
172  result = &SifRpcTxBuffer;
173 
174  if(TxFrameBuffer == NULL) TxFrameBuffer = malloc(NETMAN_MAX_FRAME_SIZE * NETMAN_RPC_BLOCK_SIZE);
175  if(FrameBufferStatus == NULL) FrameBufferStatus = malloc(sizeof(struct NetManBD) * NETMAN_RPC_BLOCK_SIZE);
176 
177  if(TxFrameBuffer != NULL && FrameBufferStatus != NULL)
178  {
179  EEFrameBufferStatus = ((struct NetManRegNetworkStack*)buffer)->FrameBufferStatus;
180  memset(FrameBufferStatus, 0, sizeof(struct NetManBD) * NETMAN_RPC_BLOCK_SIZE);
181  memset(TxFrameBuffer, 0, NETMAN_MAX_FRAME_SIZE * NETMAN_RPC_BLOCK_SIZE);
182  SifRpcTxBuffer.RegNetworkStackResult.FrameBuffer = TxFrameBuffer;
183  IOPFrameBufferRdPtr = 0;
184  ResultValue = NetManRegisterNetworkStack(&RpcStack);
185 
186  if(ResultValue == 0)
187  sceSifAddCmdHandler(NETMAN_SIFCMD_ID, &HandleRxEvent, NULL);
188  }else{
189  ResultValue = -ENOMEM;
190  }
191 
192  IsRpcStackInitialized=1;
193  SifRpcTxBuffer.RegNetworkStackResult.result = ResultValue;
194  SifRpcTxBuffer.RegNetworkStackResult.FrameBufferStatus = FrameBufferStatus;
195  break;
196  case NETMAN_IOP_RPC_FUNC_UNREG_NETWORK_STACK:
197  unregisterEENetworkStack();
198  result=NULL;
199  break;
200  case NETMAN_IOP_RPC_FUNC_IOCTL:
201  SifRpcTxBuffer.IoctlResult.result=NetManIoctl(((struct NetManIoctl*)buffer)->command, ((struct NetManIoctl*)buffer)->args, ((struct NetManIoctl*)buffer)->args_len, SifRpcTxBuffer.IoctlResult.output, ((struct NetManIoctl*)buffer)->length);
202  result=&SifRpcTxBuffer;
203  break;
204  case NETMAN_IOP_RPC_FUNC_SET_MAIN_NETIF:
205  SifRpcTxBuffer.result=NetManSetMainIF(buffer);
206  result=&SifRpcTxBuffer;
207  break;
208  case NETMAN_IOP_RPC_FUNC_QUERY_MAIN_NETIF:
209  SifRpcTxBuffer.QueryMainNetIFResult.result=NetManQueryMainIF(SifRpcTxBuffer.QueryMainNetIFResult.name);
210  result=&SifRpcTxBuffer;
211  break;
212  case NETMAN_IOP_RPC_FUNC_SET_LINK_MODE:
213  ResultValue=NetManSetLinkMode(*(s32*)buffer);
214  result=&ResultValue;
215  break;
216  default:
217  printf("NETMAN [IOP]: Unrecognized command: 0x%x\n", fno);
218  ResultValue=-1;
219  result=&ResultValue;
220  }
221 
222  return result;
223 }
224 
225 static void NETMAN_RPC_srv(void *args)
226 {
227  (void)args;
228 
229  sceSifSetRpcQueue(&rpc_qdata, RpcThreadID);
230 
231  sceSifRegisterRpc(&rpc_sdata, NETMAN_RPC_NUMBER, &NETMAN_rpc_handler, rpc_buffer, NULL, NULL, &rpc_qdata);
232  sceSifRpcLoop(&rpc_qdata);
233 }
234 
235 int NetmanInitRPCServer(void)
236 {
237  iop_thread_t ThreadData;
238 
239  if(!IsInitialized)
240  {
241  ThreadData.attr=TH_C;
242  ThreadData.option=0;
243  ThreadData.thread=&NETMAN_RPC_srv;
244  ThreadData.stacksize=0x600;
245  ThreadData.priority=0x27; //Should have higher priority than the IF driver thread, in order to dump frames in the IOP before returning.
246 
247  StartThread(RpcThreadID=CreateThread(&ThreadData), NULL);
248  IsInitialized=1;
249  }
250 
251  return 0;
252 }
253 
254 void NetmanDeinitRPCServer(void)
255 {
256  if(IsInitialized)
257  {
258  sceSifRemoveRpc(&rpc_sdata, &rpc_qdata);
259  sceSifRemoveRpcQueue(&rpc_qdata);
260 
261  TerminateThread(RpcThreadID);
262  DeleteThread(RpcThreadID);
263  IsInitialized=0;
264  }
265 }
NetManPktCmd
Definition: netman_rpc.h:75
NetManIoctlResult
Definition: netman_rpc.h:69
NetManRegNetworkStack
Definition: netman_rpc.h:39
NetManNetProtStack
Definition: netman.h:16
thbase.h
sifman.h
sysclib.h
__attribute__
static int rpc_buffer[18000/4] __attribute__((__aligned__(4)))
ENOMEM
#define ENOMEM
Definition: errno.h:43
NetManQueryMainNetIFResult
Definition: netman_rpc.h:51
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
loadcore.h
t_SifCmdHeader
Definition: sifcmd-common.h:22
netman.h
thsemap.h
netman_rpc.h
stdio.h
_iop_thread
Definition: thbase.h:39
NetManRegNetworkStackResult
Definition: netman_rpc.h:44
t_SifDmaTransfer
Definition: sifdma.h:52
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
t_SifRpcServerData
Definition: sifrpc-common.h:98
t_SifRpcDataQueue
Definition: sifrpc-common.h:153
NetManIoctl
Definition: netman_rpc.h:60
NetManBD
Definition: netman_rpc.h:82
intrman.h
thevent.h
errno.h