Last active
June 10, 2018 19:42
-
-
Save hax0kartik/3a919e4c2b008d3679c9c34c11df3616 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <3ds.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <wchar.h> | |
static Handle frdHandle; | |
static int frdRefCount; | |
static Handle s_terminate; | |
Result frdInit(void) | |
{ | |
Result ret = 0; | |
if (AtomicPostIncrement(&frdRefCount)) | |
return 0; | |
ret = srvGetServiceHandle(&frdHandle, "frd:a"); | |
if (R_FAILED(ret)) | |
AtomicDecrement(&frdRefCount); | |
return ret; | |
} | |
void frdExit(void) | |
{ | |
if (AtomicDecrement(&frdRefCount)) | |
return; | |
svcCloseHandle(frdHandle); | |
} | |
Result FRD_FriendCodeToPrincipalId(u64 friendCode, u32 * principalId) | |
{ | |
Result ret = 0; | |
u32 * cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = IPC_MakeHeader(0x25, 2, 0); // 0x00250080 | |
cmdbuf[1] = (u32)(friendCode & 0xFFFFFFFF); | |
cmdbuf[2] = (u32)(friendCode >> 32); | |
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) | |
return ret; | |
*principalId = cmdbuf[2]; | |
return cmdbuf[1]; | |
} | |
typedef struct | |
{ | |
u32 principal_id; | |
u32 padding; | |
u64 local_friend_code; | |
}frd_key; | |
Result FRD_RemoveFriend(u32 principal_id, u64 local_friend_code) | |
{ | |
Result ret = 0; | |
u32 *cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x4090100; | |
cmdbuf[1] = principal_id; | |
cmdbuf[2] = local_friend_code & 0xffffffff; | |
cmdbuf[3] = (local_friend_code >> 32) & 0xffffffff; | |
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) | |
return ret; | |
return cmdbuf[1]; | |
} | |
Result FRD_IsValidFriendCode(u64 friendCode, bool * isValid) | |
{ | |
Result ret = 0; | |
u32 * cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = IPC_MakeHeader(0x26, 2, 0); // 0x00260080 | |
cmdbuf[1] = (u32)(friendCode & 0xFFFFFFFF); | |
cmdbuf[2] = (u32)(friendCode >> 32); | |
if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) | |
return ret; | |
*isValid = cmdbuf[2] & 0xFF; | |
return cmdbuf[1]; | |
} | |
typedef enum | |
{ | |
self_online = 1, | |
self_offline, | |
friend_online, | |
friend_presence, | |
friend_mii, | |
friend_profile, | |
friend_offline, | |
friend_became_friend, | |
friend_invitaton | |
}friend_notif_types; | |
typedef struct | |
{ | |
u8 type; | |
u8 padding3[3]; | |
u32 padding; | |
frd_key key; | |
}friend_notif_event; | |
Result FRD_GetEventNotification(friend_notif_event *event, size_t size, u32 *recieved_notif_count) | |
{ | |
Result ret = 0; | |
u32 *cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x220040; | |
cmdbuf[1] = (u32)size; | |
u32 *staticbuf = getThreadStaticBuffers(); | |
staticbuf[0] = 0x60000 * size | 2; | |
staticbuf[1] = (u32)event; | |
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) | |
return ret; | |
*recieved_notif_count = cmdbuf[3]; | |
return (Result)cmdbuf[1]; | |
} | |
Result FRD_addFriendOnline(Handle event,u32 principal_id) | |
{ | |
Result ret = 0; | |
u32 *cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x4060042; | |
cmdbuf[1] = principal_id; | |
cmdbuf[2] = 0; | |
cmdbuf[3] = (u32)event; | |
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; | |
return (Result)cmdbuf[1]; | |
} | |
Result FRD_AttachToEventNotification(Handle event) | |
{ | |
Result ret = 0; | |
u32 *cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x200002; | |
cmdbuf[1] = 0; | |
cmdbuf[2] = (u32)event; | |
if(R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; | |
return (Result)cmdbuf[1]; | |
} | |
void HandleFriendNotification(friend_notif_event *event) | |
{ | |
switch(event->type) | |
{ | |
case friend_became_friend: | |
printf("registered %lx as a friend", event->key.principal_id); | |
break; | |
case friend_online: | |
printf("%lx is online", event->key.principal_id); | |
break; | |
case friend_offline: | |
printf("%lx is offline", event->key.principal_id); | |
break; | |
default: | |
printf("notification %d recieved for %lx", event->type, event->key.principal_id); | |
break; | |
} | |
} | |
void FriendNotificationHandlerThread(void *n) | |
{ | |
printf("HandlerThreadCreated()\n"); | |
Handle friendsEvent; | |
svcCreateEvent(&friendsEvent, RESET_ONESHOT); | |
Result res = FRD_AttachToEventNotification(friendsEvent); | |
if(res != 0) printf("Error in AttachingEventHandle %08lX", res); | |
s32 out; | |
Handle frd_handles[] = {friendsEvent, s_terminate}; | |
bool run = true; | |
friend_notif_event events[10]; | |
size_t event_list_size = 10; | |
while(run) | |
{ | |
svcWaitSynchronizationN(&out, frd_handles, 2, false, U64_MAX); | |
printf("out %d\n", out); | |
switch(out) | |
{ | |
case 0: | |
{ | |
size_t size = 0; | |
do | |
{ | |
res = FRD_GetEventNotification(events, 10, (u32 *)&size); | |
printf("GetEventNotification %08lX\n", res); | |
for(int i = 0; i < size; ++i) | |
{ | |
HandleFriendNotification(events + i); | |
} | |
}while(size!=0); | |
break; | |
} | |
case 1: | |
run = false; | |
break; | |
} | |
} | |
svcClearEvent(s_terminate); | |
printf("Deinitialization finished\n"); | |
} | |
int main(void) | |
{ | |
gfxInitDefault(); | |
consoleInit(GFX_TOP, NULL); | |
Result res = frdInit(); | |
printf("frdinit: %08lX\n", res); | |
SwkbdState swkbd; | |
char mybuf[60]; | |
u64 frd_code; | |
bool pid; | |
u32 pid_2; | |
Handle event; | |
svcCreateEvent(&event, RESET_ONESHOT); | |
svcCreateEvent(&s_terminate, RESET_ONESHOT); | |
printf("Going To init thread\n"); | |
Thread thread = threadCreate(FriendNotificationHandlerThread, NULL, 4096 * 2, 0x24, 0, true); | |
printf("Press A to continue\n"); | |
while(aptMainLoop()) | |
{ | |
hidScanInput(); | |
if(keysDown() & KEY_A) | |
{ | |
swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 3, -1); | |
swkbdSetHintText(&swkbd, "Please enter a friend-code without \"-\" "); | |
swkbdInputText(&swkbd, mybuf, sizeof(mybuf)); | |
sscanf(mybuf,"%lld", &frd_code); | |
printf("frd_code %lld\n", frd_code); | |
//frd_key a; | |
//a.local_friend_code = frd_code; | |
printf("FRD_FriendCodeIsValid() %08lX \n", FRD_IsValidFriendCode(frd_code,&pid)); | |
printf("fc is valid: %s\n", (pid == 1) ? "True": "False"); | |
printf("FRD_FriendCodeToPrincipalId() %08lx\n", FRD_FriendCodeToPrincipalId(frd_code,&pid_2)); | |
printf("Principal_id %lx\n", pid_2); | |
printf("FRD_addFriend() %08lx\n", FRD_addFriendOnline(event, pid_2)); | |
//printf("Reboot tiltle set."); | |
} | |
if(keysDown() & KEY_START) | |
{ | |
break; | |
} | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
} | |
printf("Going to signal Thread"); | |
svcSignalEvent(s_terminate); | |
threadJoin(thread, U64_MAX); | |
svcCloseHandle(s_terminate); | |
frdExit(); | |
gfxExit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment