Line 240:
Line 240:
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic.
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic.
|}
|}
+
+
+
== SVCs ==
+
+
=== svcReplyAndReceive ===
+
+
'''Signature:'''
+
Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)
+
+
In a single operation, sends a IPC reply and waits for a new request. <code>handles</code> should be a pointer to an array of <code>handleCount</code> handles.<sup>TODO: Are only port/session handles supported?</sup>
+
<code>replyTarget</code> should contain a handle to the session to send the reply to. (This us usually the session from which we received the previous request.)
+
If <code>replyTarget</code> is 0, no reply and the call will simply wait for an incoming event.<sup>TODO: It doesn't seem like the 0xFFFF0000 command id mentioned in the above sections is necessary, but needs confirmation.</sup>
+
+
Upon returning, <code>index</code> will contain an index into <code>handles</code> specifying which object changed state.
+
If it's a server port endpoint, it means that there is a new incoming connection on that port which should be accepted using svcAcceptSession.
+
If it's a server session endpoint it means that we received a request from that session and should process and then reply to it by calling svcReplyAndReceive again with <code>replyTarget</code> set to that session's handle.
+
+
An example of a server svcReplyAndReceive loop is:
+
+
#define MAX_CLIENTS 4
+
Handle server_port = ...;
+
s32 requesting_index;
+
Handle handles[1 + MAX_CLIENTS] = { server_port };
+
s32 connected_clients = 0;
+
Handle reply_target = 0;
+
+
while (true) {
+
Result res = svcReplyAndReceive(&requesting_index, &handles, 1 + connected_clients, reply_target);
+
+
if (res == 0xC920181A) {
+
// Session was closed by remote
+
// TODO: Handle disconnects
+
reply_target = 0;
+
continue;
+
}
+
+
if (requesting_index == 0) {
+
// New connection in server_port
+
ASSERT(connected_client < MAX_CLIENTS);
+
svcAcceptSession(&handles[1 + connected_clients++], server_port);
+
reply_target = 0;
+
continue;
+
}
+
+
reply_target = handles[requesting_index];
+
+
// Handle command here and write reply to command buffer
+
}