Guest User

Untitled

a guest
Apr 19th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.27 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include <ogcsys.h>
  6. #include <gccore.h>
  7. #include <ogc/ipc.h>
  8. #include <stdarg.h>
  9. #include <ctype.h>
  10.  
  11. static void *xfb = NULL;
  12. static GXRModeObj *rmode = NULL;
  13.  
  14. int btm_fd;
  15.  
  16. typedef void (*Loader_Entry)(void);
  17.  
  18. //Loader_Entry loader = (Loader_Entry)0x90000020;
  19. Loader_Entry loader = (Loader_Entry)0x80001800;
  20.  
  21. char ascii(char s) {
  22. if(s < 0x20) return '.';
  23. if(s > 0x7E) return '.';
  24. return s;
  25. }
  26.  
  27. void hexdump(void *d, int len)
  28. {
  29. u8 *data;
  30. int off=0;
  31. int i;
  32. data = (u8*)d;
  33. while(off<len) {
  34. printf("%08x ",off);
  35. for(i=0; i<8; i++) {
  36. if((i+off)>=len) {
  37. printf(" ");
  38. } else {
  39. printf("%02x ",data[off+i]);
  40. }
  41. }
  42. printf(" ");
  43. for(i=0; i<8; i++) {
  44. if((i+off)>=len) {
  45. printf(" ");
  46. } else {
  47. printf("%c",ascii(data[off+i]));
  48. }
  49. }
  50. printf("\n");
  51. off +=8;
  52. }
  53. }
  54.  
  55. //HACK for now
  56. #define _ipc_hid 0
  57.  
  58. struct _ioctlv_fmt_bufent {
  59. void *ipc_buf;
  60. void *output_buf;
  61. s32 copy_len;
  62. };
  63.  
  64. struct _ioctlv_fmt_cbdata {
  65. ipccallback user_cb;
  66. void *usrdata;
  67. s32 num_bufs;
  68. struct _ioctlv_fmt_bufent *bufs;
  69. };
  70.  
  71. s32 _ioctlv_fmt_cb(s32 result,void *usrdata)
  72. {
  73. struct _ioctlv_fmt_cbdata *cbdata;
  74. struct _ioctlv_fmt_bufent *pbuf;
  75. cbdata = (struct _ioctlv_fmt_cbdata*) usrdata;
  76. ipccallback user_cb;
  77. void *user_data;
  78.  
  79. // deal with data buffers
  80. if(cbdata->bufs) {
  81. pbuf = cbdata->bufs;
  82. while(cbdata->num_bufs--) {
  83. if(pbuf->ipc_buf) {
  84. // copy data if needed
  85. if(pbuf->output_buf && pbuf->copy_len)
  86. memcpy(pbuf->output_buf, pbuf->ipc_buf, pbuf->copy_len);
  87. // then free the buffer
  88. iosFree(_ipc_hid, pbuf->ipc_buf);
  89. }
  90. pbuf++;
  91. }
  92. }
  93.  
  94. user_cb = cbdata->user_cb;
  95. user_data = cbdata->usrdata;
  96.  
  97. // free buffer list
  98. iosFree(_ipc_hid, cbdata->bufs);
  99.  
  100. // free callback data
  101. iosFree(_ipc_hid, cbdata);
  102.  
  103. // call the user callback
  104. if(user_cb)
  105. return user_cb(result, user_data);
  106. else
  107. return 0;
  108.  
  109. }
  110.  
  111. s32 _ios_ioctlv_fmt_parse(const char *format, va_list args, struct _ioctlv_fmt_cbdata *cbdata, s32 *cnt_in, s32 *cnt_io, ioctlv **argv)
  112. {
  113. int max_bufs;
  114. ioctlv *argp;
  115. struct _ioctlv_fmt_bufent *bufp;
  116. char type;
  117. int i;
  118. int ret;
  119. int len;
  120. char *ps;
  121.  
  122. void *pdata;
  123. void *iodata;
  124.  
  125. // this is an overestimation and includes a potential extra entry for the ':' separator
  126. // but that's okay
  127. max_bufs = strnlen(format,32);
  128. // sanity check
  129. if(max_bufs >= 32) return IPC_EINVAL;
  130.  
  131. // allocate callback buffer list
  132. // max_bufs+1, since the first buffer to free is argv itself
  133. cbdata->bufs = iosAlloc(_ipc_hid, sizeof(struct _ioctlv_fmt_bufent)*(max_bufs+1));
  134. if(!cbdata->bufs) {
  135. return IPC_ENOMEM;
  136. }
  137. memset(cbdata->bufs, 0, sizeof(struct _ioctlv_fmt_bufent)*(max_bufs+1));
  138. bufp = cbdata->bufs;
  139.  
  140. // allocate ioctl argv array
  141. argp = iosAlloc(_ipc_hid, sizeof(ioctlv)*max_bufs);
  142. if(!argp) {
  143. iosFree(_ipc_hid, cbdata->bufs);
  144. return IPC_ENOMEM;
  145. }
  146. memset(argp, 0, sizeof(ioctlv)*max_bufs);
  147. *argv = argp; //pass array to caller for ioctlv()
  148.  
  149. // first buffer is argp
  150. cbdata->num_bufs = 1;
  151. bufp->ipc_buf = argp;
  152. bufp++;
  153.  
  154. *cnt_in = 0;
  155. *cnt_io = 0;
  156.  
  157. ret = 0;
  158.  
  159. //parse the input arguments
  160. while(*format) {
  161. type = tolower(*format);
  162. switch(type) {
  163. case 'b':
  164. pdata = iosAlloc(_ipc_hid, 1);
  165. if(!pdata) {
  166. ret = IPC_ENOMEM;
  167. goto free_and_error;
  168. }
  169. *(u8*)pdata = va_arg(args, u32); //u32 because of promotion
  170. argp->data = pdata;
  171. argp++->len = 1;
  172. ++*cnt_in;
  173. bufp++->ipc_buf = pdata;
  174. cbdata->num_bufs++;
  175. break;
  176. case 'h':
  177. pdata = iosAlloc(_ipc_hid, 2);
  178. if(!pdata) {
  179. ret = IPC_ENOMEM;
  180. goto free_and_error;
  181. }
  182. *(u16*)pdata = va_arg(args, u32); //u32 because of promotion
  183. argp->data = pdata;
  184. argp++->len = 2;
  185. ++*cnt_in;
  186. bufp++->ipc_buf = pdata;
  187. cbdata->num_bufs++;
  188. break;
  189. case 'i':
  190. pdata = iosAlloc(_ipc_hid, 4);
  191. if(!pdata) {
  192. ret = IPC_ENOMEM;
  193. goto free_and_error;
  194. }
  195. *(u32*)pdata = va_arg(args, u32);
  196. argp->data = pdata;
  197. argp++->len = 4;
  198. ++*cnt_in;
  199. bufp++->ipc_buf = pdata;
  200. cbdata->num_bufs++;
  201. break;
  202. case 'd':
  203. argp->data = va_arg(args, void *);
  204. argp++->len = va_arg(args, u32);
  205. ++*cnt_in;
  206. break;
  207. case 's':
  208. ps = va_arg(args, char *);
  209. len = strnlen(ps, 256);
  210. if(len >= 256) { // sanity check
  211. ret = IPC_EINVAL;
  212. goto free_and_error;
  213. }
  214. pdata = iosAlloc(_ipc_hid, len+1);
  215. if(!pdata) {
  216. ret = IPC_ENOMEM;
  217. goto free_and_error;
  218. }
  219. memcpy(pdata, ps, len+1);
  220. argp->data = pdata;
  221. argp++->len = len+1;
  222. ++*cnt_in;
  223. bufp++->ipc_buf = pdata;
  224. cbdata->num_bufs++;
  225. break;
  226. case ':':
  227. format++; // skip colon
  228. goto parse_io_parms;
  229. default:
  230. ret = IPC_EINVAL;
  231. goto free_and_error;
  232. }
  233. format++;
  234. }
  235.  
  236. parse_io_parms:
  237. //parse the input/output arguments
  238. while(*format) {
  239. type = tolower(*format);
  240. switch(type) {
  241. case 'b':
  242. pdata = iosAlloc(_ipc_hid, 1);
  243. if(!pdata) {
  244. ret = IPC_ENOMEM;
  245. goto free_and_error;
  246. }
  247. iodata = va_arg(args, u8 *);
  248. *(u8*)pdata = *(u8*)iodata;
  249. argp->data = pdata;
  250. argp++->len = 1;
  251. ++*cnt_io;
  252. bufp->ipc_buf = pdata;
  253. bufp->output_buf = iodata;
  254. bufp++->copy_len = 1;
  255. cbdata->num_bufs++;
  256. break;
  257. case 'h':
  258. pdata = iosAlloc(_ipc_hid, 1);
  259. if(!pdata) {
  260. ret = IPC_ENOMEM;
  261. goto free_and_error;
  262. }
  263. iodata = va_arg(args, u16 *);
  264. *(u16*)pdata = *(u16*)iodata;
  265. argp->data = pdata;
  266. argp++->len = 2;
  267. ++*cnt_io;
  268. bufp->ipc_buf = pdata;
  269. bufp->output_buf = iodata;
  270. bufp++->copy_len = 2;
  271. cbdata->num_bufs++;
  272. break;
  273. case 'i':
  274. pdata = iosAlloc(_ipc_hid, 4);
  275. if(!pdata) {
  276. ret = IPC_ENOMEM;
  277. goto free_and_error;
  278. }
  279. iodata = va_arg(args, u32 *);
  280. *(u32*)pdata = *(u32*)iodata;
  281. argp->data = pdata;
  282. argp++->len = 4;
  283. ++*cnt_io;
  284. bufp->ipc_buf = pdata;
  285. bufp->output_buf = iodata;
  286. bufp++->copy_len = 4;
  287. cbdata->num_bufs++;
  288. break;
  289. case 'd':
  290. argp->data = va_arg(args, void *);
  291. argp++->len = va_arg(args, u32);
  292. ++*cnt_io;
  293. break;
  294. default:
  295. ret = IPC_EINVAL;
  296. goto free_and_error;
  297. }
  298. format++;
  299. }
  300.  
  301. return *cnt_in + *cnt_io;
  302.  
  303. // free up all allocated buffers
  304. free_and_error:
  305. // this includes argv
  306. for(i=0; i<cbdata->num_bufs; i++) {
  307. iosFree(_ipc_hid, cbdata->bufs[i].ipc_buf);
  308. }
  309. // free buffers structure
  310. iosFree(_ipc_hid, cbdata->bufs);
  311. return ret;
  312. }
  313.  
  314. s32 IOS_Ioctlv_Fmt(s32 fd, s32 ioctl, const char *format, ...)
  315. {
  316. va_list args;
  317. int ret;
  318. s32 cnt_in, cnt_io;
  319. struct _ioctlv_fmt_cbdata *cbdata;
  320. ioctlv *argv;
  321.  
  322.  
  323. cbdata = iosAlloc(_ipc_hid, sizeof(struct _ioctlv_fmt_cbdata));
  324. memset(cbdata, 0, sizeof(struct _ioctlv_fmt_cbdata));
  325. va_start(args, format);
  326. ret = _ios_ioctlv_fmt_parse(format, args, cbdata, &cnt_in, &cnt_io, &argv);
  327. va_end(args);
  328. if(ret < 0) {
  329. iosFree(_ipc_hid, cbdata);
  330. return ret;
  331. }
  332. ret = IOS_Ioctlv(fd, ioctl, cnt_in, cnt_io, argv);
  333. // call the callback manually to free buffers / copy
  334. cbdata->user_cb = NULL;
  335. _ioctlv_fmt_cb(ret, cbdata);
  336. return ret;
  337. }
  338.  
  339. s32 IOS_IoctlvAsync_Fmt(s32 fd, s32 ioctl, ipccallback ipc_cb, void *usrdata, const char *format, ...)
  340. {
  341. va_list args;
  342. int ret;
  343. s32 cnt_in, cnt_io;
  344. struct _ioctlv_fmt_cbdata *cbdata;
  345. ioctlv *argv;
  346.  
  347.  
  348. cbdata = iosAlloc(_ipc_hid, sizeof(struct _ioctlv_fmt_cbdata));
  349. memset(cbdata, 0, sizeof(struct _ioctlv_fmt_cbdata));
  350. va_start(args, format);
  351. ret = _ios_ioctlv_fmt_parse(format, args, cbdata, &cnt_in, &cnt_io, &argv);
  352. va_end(args);
  353. if(ret < 0) {
  354. iosFree(_ipc_hid, cbdata);
  355. return ret;
  356. }
  357. cbdata->user_cb = ipc_cb;
  358. cbdata->usrdata = usrdata;
  359. ret = IOS_IoctlvAsync(fd, ioctl, cnt_in, cnt_io, argv, _ioctlv_fmt_cb, cbdata);
  360. return ret;
  361. }
  362.  
  363. //-----------------------------------------------------------------------------------
  364.  
  365. #define USB_IOCTL_CTRLMSG 0
  366. #define USB_IOCTL_BULKMSG 1
  367. #define USB_IOCTL_INTRMSG 2
  368. #define USB_IOCTL_GET_DEVICE_LIST 0xC
  369.  
  370. #define USB_CREQ_H2D 0x00
  371. #define USB_CREQ_D2H 0x80
  372. #define USB_CREQ_STANDARD 0x00
  373. #define USB_CREQ_CLASS 0x20
  374. #define USB_CREQ_VENDOR 0x40
  375. #define USB_CREQ_DEVICE 0x00
  376. #define USB_CREQ_INTERFACE 0x01
  377. #define USB_CREQ_ENDPOINT 0x02
  378. #define USB_CREQ_OTHER 0x03
  379.  
  380. #define SWAB16(x) ((((x)&0xFF)<<8)|((x)>>8))
  381.  
  382. #define ALIGNED(n) __attribute__((aligned(n)))
  383.  
  384.  
  385. int usb_ctrl_msg(int fd, u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, void* payload, u16 wLength)
  386. {
  387. // printf("USB control: %x %x %x %x %x LEN %x BUF %p\n", fd, bmRequestType, bRequest, wValue, wIndex, wLength, payload);
  388. return IOS_Ioctlv_Fmt(fd, USB_IOCTL_CTRLMSG, "bbhhhb:d", bmRequestType, bRequest, SWAB16(wValue), SWAB16(wIndex), SWAB16(wLength), 0, payload, wLength);
  389. }
  390.  
  391. // the following two functions work for both reads and writes!
  392. int usb_intr_msg(int fd, u8 bEndpoint, void* payload, u16 wLength)
  393. {
  394. // printf("USB interrupt: EP %x LEN %x BUF %p\n", bEndpoint, wLength, payload);
  395. return IOS_Ioctlv_Fmt(fd, USB_IOCTL_INTRMSG, "bh:d", bEndpoint, wLength, payload, wLength);
  396. }
  397.  
  398. int usb_bulk_msg(int fd, u8 bEndpoint, void* payload, u16 wLength)
  399. {
  400. // printf("USB bulk: EP %x LEN %x BUF %p\n", bEndpoint, wLength, payload);
  401. return IOS_Ioctlv_Fmt(fd, USB_IOCTL_BULKMSG, "bh:d", bEndpoint, wLength, payload, wLength);
  402. }
  403.  
  404. int usb_bulk_msg_async(int fd, u8 bEndpoint, void* payload, u16 wLength, ipccallback ipc_cb,void *usrdata)
  405. {
  406. // printf("USB bulk: EP %x LEN %x BUF %p\n", bEndpoint, wLength, payload);
  407. return IOS_IoctlvAsync_Fmt(fd, USB_IOCTL_BULKMSG, ipc_cb, usrdata, "bh:d", bEndpoint, wLength, payload, wLength);
  408. }
  409.  
  410. // no worky yet
  411. int usb_get_device_list(int fd, u8 type)
  412. {
  413. int ret;
  414. static u8 rcnt[0x100] ALIGNED(0x20);
  415. static u8 buf[0x80] ALIGNED(0x20);
  416. memset(buf,0,sizeof(buf));
  417. rcnt[0] = 0xFF;
  418. ret = IOS_Ioctlv_Fmt(fd, USB_IOCTL_GET_DEVICE_LIST, "bb:bd", sizeof(buf)>>3, type, rcnt, buf, sizeof(buf));
  419. printf("USB dev list %d ret %d rcnt %d data:\n",type,ret,rcnt[0]);
  420. hexdump(buf,8);
  421. return ret;
  422. }
  423.  
  424. #define EP_CONTROL 0x00
  425. #define EP_EVENTS 0x81
  426. #define EP_ACL_OUT 0x02
  427. #define EP_ACL_IN 0x82
  428.  
  429. #define HCI_G_LINKCONTROL 1
  430. #define HCI_G_LINKPOLICY 2
  431. #define HCI_G_CONTROLLER 3
  432. #define HCI_G_INFORMATIONAL 4
  433. #define HCI_G_STATUS 5
  434. #define HCI_G_TESTING 6
  435.  
  436. #define HCI_C_RESET 0x0003
  437. #define HCI_LC_CONNECT 0x0005
  438.  
  439. #define HCI_PKTTYPE_DM1 0x0008
  440. #define HCI_PSRM_R2 2
  441. #define HCI_CLKOFF_INVALID 0
  442. #define HCI_NO_ROLESWITCH 0
  443.  
  444. #define HCI_EV_CONNECTION_COMPLETE 0x03
  445.  
  446. int bt_HCI_command(int fd, int ogf, int ocf, u8 *parameters, u8 parmlength) {
  447. int opcode;
  448. static u8 buffer[0x103] ALIGNED(0x40);
  449. opcode = (ocf&0x3FF) | ((ogf &0x3F)<<10);
  450. buffer[0] = opcode&0xFF;
  451. buffer[1] = opcode>>8;
  452. buffer[2] = parmlength;
  453.  
  454. if(parameters && parmlength) {
  455. memcpy (&buffer[3], parameters, parmlength);
  456. } else {
  457. parmlength = 0; //make sure we don't pass around junk
  458. }
  459.  
  460. return usb_ctrl_msg(fd, USB_CREQ_H2D|USB_CREQ_CLASS|USB_CREQ_DEVICE, 0, 0, 0, buffer, parmlength+3);
  461. }
  462.  
  463. typedef struct {
  464. u8 event_code;
  465. u8 data_length;
  466. u8 *data;
  467. } HCI_Event;
  468.  
  469. typedef struct {
  470. u16 chnd;
  471. int pb,bc;
  472. u16 data_length;
  473. u8 *data;
  474. } HCI_ACL_Data;
  475.  
  476. int bt_HCI_recv_event(int fd, HCI_Event *ev) {
  477.  
  478. static u8 buffer[0x102] ALIGNED(0x40);
  479. int res;
  480.  
  481. res = usb_intr_msg(fd, EP_EVENTS, buffer, sizeof(buffer));
  482. ev->event_code = buffer[0];
  483. ev->data_length = buffer[1];
  484. ev->data = &buffer[2];
  485. printf("HCI event [%d]: Code 0x%x, length %d, data:\n",res,ev->event_code, ev->data_length);
  486. hexdump(ev->data, ev->data_length);
  487. return res;
  488. }
  489.  
  490. int bt_HCI_reset(int fd) {
  491.  
  492. return bt_HCI_command(fd, HCI_G_CONTROLLER, HCI_C_RESET, NULL, 0);
  493. }
  494.  
  495. int bt_HCI_connect(int fd, u8 *bdaddr, u16 pkt_types, u8 psrm, u16 clkoff, u8 roleswitch) {
  496.  
  497. static u8 data[13];
  498. int i;
  499. for(i=0;i<6;i++) data[i] = bdaddr[5-i];
  500. data[6] = pkt_types & 0xFF;
  501. data[7] = pkt_types >> 8;
  502. data[8] = psrm;
  503. data[9] = 0; //reserved
  504. data[10] = clkoff & 0xFF;
  505. data[11] = clkoff >> 8;
  506. data[12] = roleswitch;
  507.  
  508. return bt_HCI_command(fd, HCI_G_LINKCONTROL, HCI_LC_CONNECT, data, sizeof(data));
  509. }
  510.  
  511. int bt_HCI_send_ACL(int fd, u16 chnd, int pb, int bc, u16 length, u8 *data) {
  512. static u8 buffer[0x100] ALIGNED(0x40);
  513. printf("<ACL chnd %04x pb %d bc %d len %d data:\n",chnd,pb,bc,length);
  514. hexdump(data,length);
  515. chnd &= 0x0FFF;
  516. chnd |= pb<<12;
  517. chnd |= bc<<14;
  518. memcpy(&buffer[4],data,length);
  519. buffer[0] = chnd & 0xFF;
  520. buffer[1] = chnd >> 8;
  521. buffer[2] = length & 0xFF;
  522. buffer[3] = length >>8;
  523. return usb_bulk_msg(fd, EP_ACL_OUT, buffer, length+4);
  524. }
  525.  
  526. int bt_HCI_recv_ACL(int fd, HCI_ACL_Data *acl) {
  527. static u8 buffer[0x40] ALIGNED(0x40);
  528. int res;
  529.  
  530. res = usb_bulk_msg(fd, EP_ACL_IN, buffer, sizeof(buffer));
  531. acl->chnd = buffer[0] | (buffer[1]<<8);
  532. acl->pb = (acl->chnd & 0x3000)>>12;
  533. acl->bc = (acl->chnd & 0xC000)>>14;
  534. acl->chnd &= 0x0FFF;
  535. acl->data_length = buffer[2] | (buffer[3]<<8);
  536. acl->data = &buffer[4];
  537. printf(">ACL [%d]: chnd %04x pb %d bc %d len %d data:\n",res,acl->chnd, acl->pb, acl->bc, acl->data_length);
  538. hexdump(acl->data, acl->data_length);
  539. return res;
  540. }
  541.  
  542. static volatile int flag = 0;
  543. static volatile int res;
  544.  
  545. s32 _bt_cb(int r, void *data) {
  546. res = r;
  547. flag = 1;
  548. return 0;
  549. }
  550.  
  551. int bt_HCI_recv_ACL_async(int fd, HCI_ACL_Data *acl) {
  552. static u8 buffer[0x40] ALIGNED(0x40);
  553. int res;
  554. flag = 0;
  555. res = usb_bulk_msg_async(fd, EP_ACL_IN, buffer, sizeof(buffer), _bt_cb, NULL);
  556. while(!flag) {
  557. VIDEO_WaitVSync();
  558. PAD_ScanPads();
  559. int buttonsDown = PAD_ButtonsHeld(0);
  560. if( (buttonsDown & PAD_TRIGGER_Z) && (buttonsDown & PAD_BUTTON_START)) {
  561. loader();
  562. }
  563. }
  564. flag = 0;
  565. acl->chnd = buffer[0] | (buffer[1]<<8);
  566. acl->pb = (acl->chnd & 0x3000)>>12;
  567. acl->bc = (acl->chnd & 0xC000)>>14;
  568. acl->chnd &= 0x0FFF;
  569. acl->data_length = buffer[2] | (buffer[3]<<8);
  570. acl->data = &buffer[4];
  571. printf(">ACL [%d]: chnd %04x pb %d bc %d len %d data:\n",res,acl->chnd, acl->pb, acl->bc, acl->data_length);
  572. hexdump(acl->data, acl->data_length);
  573. return res;
  574. }
  575.  
  576. int bt_L2CAP_send(int fd, u16 chnd, u16 cid, u16 length, u8 *data)
  577. {
  578. static u8 buffer[0x1000] ALIGNED(0x20);
  579. memcpy(&buffer[4],data,length);
  580. buffer[0] = length & 0xFF;
  581. buffer[1] = length >> 8;
  582. buffer[2] = cid & 0xFF;
  583. buffer[3] = cid >> 8;
  584. return bt_HCI_send_ACL(fd, chnd, 2, 0, length+4, buffer);
  585. }
  586.  
  587. void checkAndReload(void) {
  588. PAD_ScanPads();
  589. int buttonsDown = PAD_ButtonsHeld(0);
  590. if( (buttonsDown & PAD_TRIGGER_Z) && (buttonsDown & PAD_BUTTON_START)) {
  591. loader();
  592. }
  593. }
  594.  
  595. int fd_stm_eh = -1;
  596. int fd_stm_imm = -1;
  597.  
  598. static u32 stm_eh_in[0x8] __attribute__((aligned(0x20)));
  599. static u32 stm_eh_out[0x8] __attribute__((aligned(0x20)));
  600.  
  601. #define IOCTL_STM_EVENTHOOK 0x1000
  602. #define IOCTL_STM_GET_IDLEMODE 0x3001
  603. #define IOCTL_STM_RELEASE_EH 0x3002
  604. #define IOCTL_STM_HOTRESET 0x2001
  605. #define IOCTL_STM_HOTRESET_FOR_PD 0x2002
  606. #define IOCTL_STM_SHUTDOWN 0x2003
  607. #define IOCTL_STM_IDLE 0x2004
  608. #define IOCTL_STM_WAKEUP 0x2005
  609. #define IOCTL_STM_VIDIMMING 0x5001
  610. #define IOCTL_STM_LEDFLASH 0x6001
  611. #define IOCTL_STM_LEDMODE 0x6002
  612. #define IOCTL_STM_READVER 0x7001
  613. #define IOCTL_STM_READDDRREG 0x4001
  614. #define IOCTL_STM_READDDRREG2 0x4002
  615.  
  616. #define LED_NOEXEC 0x2
  617. #define LED_USER 0x1
  618.  
  619. #define LED_OFF 0
  620. #define LED_DIM 1
  621. #define LED_BRIGHT 2
  622.  
  623. #define _LED_DELAY(d) \
  624. (((d)<=0) ? 0x10 :\
  625. (((d)<0x00010) ? (((((d)>>0)&15)<<4)|0) :\
  626. (((d)<0x00020) ? (((((d)>>1)&15)<<4)|1) :\
  627. (((d)<0x00040) ? (((((d)>>2)&15)<<4)|2) :\
  628. (((d)<0x00080) ? (((((d)>>3)&15)<<4)|3) :\
  629. (((d)<0x00100) ? (((((d)>>4)&15)<<4)|4) :\
  630. (((d)<0x00200) ? (((((d)>>5)&15)<<4)|5) :\
  631. (((d)<0x00400) ? (((((d)>>6)&15)<<4)|6) :\
  632. (((d)<0x00800) ? (((((d)>>7)&15)<<4)|7) :\
  633. (((d)<0x01000) ? (((((d)>>8)&15)<<4)|8) :\
  634. (((d)<0x02000) ? (((((d)>>9)&15)<<4)|9) :\
  635. (((d)<0x04000) ? (((((d)>>10)&15)<<4)|10) :\
  636. (((d)<0x08000) ? (((((d)>>11)&15)<<4)|11) :\
  637. (((d)<0x10000) ? (((((d)>>12)&15)<<4)|12) :\
  638. (((d)<0x20000) ? (((((d)>>13)&15)<<4)|13) :\
  639. (((d)<0x40000) ? (((((d)>>14)&15)<<4)|14) :\
  640. (((d)<0x80000) ? (((((d)>>15)&15)<<4)|15) :\
  641. 0xFF)))))))))))))))))
  642.  
  643. // Units of delay: 20ms
  644. // LED value: 0-128
  645. #define LED_VAL(duration, value) ((_LED_DELAY(duration)<<8) | (((value)>0x80)?0x80:(value)))
  646. #define LED_JUMP(to) ((to)&0xFF)
  647. #define LED_END (0xFF)
  648. // 2-16 loops
  649. #define LED_LOOP(iter, to) (((((iter)-1)<16)?((iter)-1):15)<<8) | LED_JUMP(to)
  650.  
  651. int stmopen(void) {
  652. if(fd_stm_imm<0) {
  653. fd_stm_imm = IOS_Open("/dev/stm/immediate",0);
  654. if(fd_stm_imm<0) {
  655. printf("Immediate open failed!\n");
  656. return -1;
  657. }
  658. }
  659. return fd_stm_imm;
  660. }
  661.  
  662. int STMCall(s32 call, void *buf1, s32 len1, void *buf2, s32 len2)
  663. {
  664. stmopen();
  665. return IOS_Ioctl(fd_stm_imm, call, buf1, len1, buf2, len2);
  666. }
  667.  
  668. void ReleaseOldSTMCallback(void) {
  669. int ret;
  670. ret = STMCall(IOCTL_STM_RELEASE_EH, NULL, 0, NULL, 0);
  671. if(ret >= 0)
  672. printf("Old callback released!\n");
  673. else if(ret == -6)
  674. printf("No old callback existed, so none was released\n");
  675. else
  676. printf("Eventhook release failed with code %d\n",ret);
  677. }
  678.  
  679. s32 stm_cb(s32 result, void *data) {
  680. int ret;
  681.  
  682. if(result < 0) {
  683. printf("STM callback: Eventhook failed with code %d\n",result);
  684. return 0;
  685. }
  686. printf("STM callback: %d %08x %08x %08x %08x\n",result,stm_eh_out[0],stm_eh_out[1],stm_eh_out[2],stm_eh_out[3]);
  687.  
  688. if(stm_eh_out[0]==0x20000) {
  689. loader();
  690. }
  691.  
  692. memset(stm_eh_out,0,0x20);
  693. ret = IOS_IoctlAsync(fd_stm_eh,IOCTL_STM_EVENTHOOK, stm_eh_in, 0x20, stm_eh_out, 0x20, stm_cb, NULL);
  694. return 0;
  695. }
  696.  
  697. void installResetCallback(void) {
  698.  
  699. int ret;
  700.  
  701. fd_stm_eh = IOS_Open("/dev/stm/eventhook",0);
  702. if(fd_stm_eh<0) {
  703. printf("Event hook open failed!\n");
  704. return;
  705. }
  706. memset(stm_eh_in,0,0x20);
  707. memset(stm_eh_out,0,0x20);
  708. ret = IOS_IoctlAsync(fd_stm_eh,IOCTL_STM_EVENTHOOK, stm_eh_in, 0x20, stm_eh_out, 0x20, stm_cb, NULL);
  709. if(ret<0) {
  710. printf("Eventhook install failed with code %d\n",ret);
  711. }
  712. }
  713.  
  714. void waita(void) {
  715. while(1) {
  716. VIDEO_WaitVSync();
  717. PAD_ScanPads();
  718. int buttonsDown = PAD_ButtonsDown(0);
  719. if(buttonsDown & PAD_BUTTON_A)
  720. return;
  721. if( (buttonsDown & PAD_TRIGGER_Z) && (buttonsDown & PAD_BUTTON_START)) {
  722. loader();
  723. }
  724. }
  725. }
  726.  
  727. u8 resetcmd[3] __attribute__((aligned(32))) = {
  728. 0x03,0x0C,0x00
  729. };
  730.  
  731. void printvers(void) {
  732. printf("3140: %08x\n", *((u32*)0xC0003140));
  733. printf("3144: %08x\n", *((u32*)0xC0003144));
  734. }
  735.  
  736. int main(int argc, char **argv) {
  737.  
  738. static u8 buf[16] __attribute__((aligned(32)));
  739. int ret;
  740. int i;
  741. HCI_Event hciev;
  742. HCI_ACL_Data acldat;
  743. u16 dcid;
  744. u8 l2pkt[32];
  745. static u32 stmpk[0x20] __attribute__((aligned(32)));
  746. static u32 stmout[0x20] __attribute__((aligned(32)));
  747.  
  748. u32 buffer;
  749.  
  750. VIDEO_Init();
  751. PAD_Init();
  752.  
  753. switch(VIDEO_GetCurrentTvMode()) {
  754. case VI_NTSC:
  755. rmode = &TVNtsc480IntDf;
  756. break;
  757. case VI_PAL:
  758. rmode = &TVPal528IntDf;
  759. break;
  760. case VI_MPAL:
  761. rmode = &TVMpal480IntDf;
  762. break;
  763. default:
  764. rmode = &TVNtsc480IntDf;
  765. break;
  766. }
  767.  
  768. xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
  769. console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
  770.  
  771. VIDEO_Configure(rmode);
  772. VIDEO_SetNextFramebuffer(xfb);
  773. VIDEO_SetBlack(FALSE);
  774. VIDEO_Flush();
  775. VIDEO_WaitVSync();
  776. if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
  777.  
  778.  
  779. printf("\n\nHello World!\n");
  780.  
  781. // printf("Closing FDs...\n");
  782. // for(i=0; i<14; i++) {
  783. // ret = IOS_Close(i);
  784. // }
  785.  
  786. // ReleaseOldSTMCallback();
  787.  
  788. installResetCallback();
  789. int es;
  790.  
  791. /*
  792. stmpk[0] = 1;
  793. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  794. stmpk[0] = 5;
  795. res = STMCall(IOCTL_STM_LEDFLASH,stmpk,4,NULL,0);
  796.  
  797.  
  798.  
  799. printvers();
  800.  
  801. int num;
  802. static u32 title[2] __attribute__((aligned(32)));
  803. static u8 views[0xD8*16] __attribute__((aligned(32)));
  804.  
  805. ioctlv vectors[3];
  806.  
  807. title[0] = 1;
  808. title[1] = 35;
  809.  
  810. es = IOS_Open("/dev/es",0);
  811. printf("Opening ES: %d\n",es);
  812.  
  813. if(es >= 0) {
  814. vectors[0].data = title;
  815. vectors[0].len = 8;
  816. vectors[1].data = &num;
  817. vectors[1].len = 4;
  818. IOS_Ioctlv(es, 0x12, 1, 1, vectors);
  819. printf("Views: %d\n",num);
  820. if(num == 1) {
  821. vectors[0].data = title;
  822. vectors[0].len = 8;
  823. vectors[1].data = &num;
  824. vectors[1].len = 4;
  825. vectors[2].data = views;
  826. vectors[2].len = 0xD8;
  827. IOS_Ioctlv(es, 0x13, 2, 1, vectors);
  828. vectors[0].data = title;
  829. vectors[0].len = 8;
  830. vectors[1].data = views;
  831. vectors[1].len = 0xD8;
  832. printf("Rebooting IOS...\n");
  833. IOS_IoctlvReboot(es, 8, 2, 0, vectors);
  834. printf("We're alive!\n");
  835. }
  836. }
  837. printvers();
  838. */
  839. // installResetCallback();
  840.  
  841.  
  842. /* do {
  843. fd_stm_imm=-1;
  844. stmopen();
  845. //printf("STM open: %d\n",stmopen());
  846. } while(fd_stm_imm > 0);
  847. */
  848. //es = IOS_Open("/dev/es",0);
  849. //printf("Opening ES: %d\n",es);
  850.  
  851. /*
  852. stmpk[0] = 1;
  853. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  854.  
  855. stmpk[0] = 0x8000+20;
  856. res = IOS_Ioctl(fd_stm_imm, IOCTL_STM_LEDFLASH, stmpk, 4, NULL, 0);
  857. printf("STM call %04x: %d\n",0x8000,res);
  858.  
  859. while(1) {
  860. waita();
  861. stmpk[0] = 1;
  862. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  863. waita();
  864. stmpk[0] = 2;
  865. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  866. }
  867. */
  868. /*
  869. stmpk[0] = LED_BRIGHT;
  870. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  871.  
  872. static u16 stmdata[130];
  873. u16 *pattern;
  874. int pos = 0;
  875. int loop;
  876. int iloop;
  877.  
  878. memset(stmdata,0,260);
  879. stmdata[0] = LED_USER;
  880. stmdata[1] = 0x8000;
  881.  
  882. pattern = &stmdata[2];
  883.  
  884. loop = pos;
  885. for(i=1;i<=16;i++) { // blink while increasing brightness
  886. pattern[pos++] = LED_VAL(1,0);
  887. pattern[pos++] = LED_VAL(1,0x10+i*7);
  888. }
  889. for(i=0;i<4;i++) { //loops 4*16 = 64 times
  890. iloop = pos;
  891. pattern[pos++] = LED_VAL(1,0); //blink at max brightness
  892. pattern[pos++] = LED_VAL(1,0x80);
  893. pattern[pos++] = LED_LOOP(16,iloop); //max loop is 16
  894. }
  895. for(i=16;i>0;i--) {
  896. pattern[pos++] = LED_VAL(1,0); // blink while descreasing brightness
  897. pattern[pos++] = LED_VAL(1,0x10+i*7);
  898. }
  899. pattern[pos++] = LED_VAL(30,0); // 30 off
  900. iloop = pos;
  901. for(i=0;i<=8;i++) {
  902. pattern[pos++] = LED_VAL(1,i*16); // fade in
  903. }
  904. for(i=8;i>=0;i--) {
  905. pattern[pos++] = LED_VAL(1,i*16); // fade out
  906. }
  907. pattern[pos++] = LED_LOOP(2,iloop); // loop the former twice
  908. pattern[pos++] = LED_VAL(6,0); // then 6 off
  909. pattern[pos++] = LED_JUMP(loop); // loop everything
  910. hexdump(pattern,2*pos);
  911. res = STMCall(IOCTL_STM_LEDFLASH,stmdata,260,NULL,0);
  912. printf("Res: %d\n",res);
  913. */
  914. /*
  915. btm_fd = IOS_Open("/dev/usb/kbd",0);
  916. printf("IOS open KBD: %d\n",btm_fd);
  917.  
  918. buf[0] = 0;
  919. buf[1] = 0;
  920.  
  921. for(i=0;i<256;i++) {
  922. buf[0] = i;
  923. res = IOS_Write(btm_fd, buf, 8);
  924. if(res>=0) printf("Write res %d: %d\n",i,res);
  925. }
  926.  
  927. while(1) {
  928. IOS_Ioctl(btm_fd, 1, NULL, 0, buf, 16);
  929. hexdump(buf,16);
  930. }
  931. */
  932. /*
  933. stmpk[0] = 1;
  934. res = STMCall(IOCTL_STM_LEDMODE,stmpk,4,NULL,0);
  935. stmpk[0] = 5;
  936. res = STMCall(IOCTL_STM_LEDFLASH,stmpk,4,NULL,0);
  937. */
  938.  
  939. // Module's VID and PID
  940.  
  941. btm_fd = IOS_Open("/dev/usb/oh1/57e/305",0);
  942. printf("IOS open USB: %d\n",btm_fd);
  943.  
  944. IOS_Ioctlv_Fmt(btm_fd, USB_IOCTL_CTRLMSG, "bbhhhb:d", 0x20, 0, 0, 0, 0x0300, 0, resetcmd, 3);
  945.  
  946.  
  947.  
  948.  
  949. // Bluetooth HCI reset command
  950. memcpy(buf,"\x03\x0c\x00",3);
  951. // Bluetooth request to control endpoint
  952. ret = IOS_Ioctlv_Fmt(btm_fd, 0, "bbhhhb:d", 0x20, 0, 0, 0, 0x0300, 0, buf, 3);
  953. printf("IOS ioctlv USB: %d\n",ret);
  954.  
  955.  
  956. if(btm_fd>0) {
  957. ret = bt_HCI_reset(btm_fd);
  958. printf("HCI reset to %d returned %d\n",btm_fd,ret);
  959. ret = bt_HCI_recv_event(btm_fd, &hciev);
  960. ret = bt_HCI_connect(btm_fd, (u8*)"\x00\x17\xAB\x33\x37\x65", HCI_PKTTYPE_DM1, HCI_PSRM_R2, HCI_CLKOFF_INVALID, HCI_NO_ROLESWITCH);
  961. printf("HCI connect to %d returned %d\n",btm_fd,ret);
  962. ret = bt_HCI_recv_event(btm_fd, &hciev);
  963. while(1) {
  964. checkAndReload();
  965. ret = bt_HCI_recv_event(btm_fd, &hciev);
  966. if(hciev.event_code == HCI_EV_CONNECTION_COMPLETE) {
  967. break;
  968. }
  969. VIDEO_WaitVSync();
  970. }
  971. if(hciev.data[0]) {
  972. printf("Connection failed!\n");
  973. } else {
  974. u16 chnd;
  975. chnd = hciev.data[1] | (hciev.data[2]<<8);
  976. printf("Connection successful! chnd: 0x%04x\n",chnd);
  977. ret = bt_L2CAP_send(btm_fd, chnd, 1, 8, (u8*)"\x02\x01\x04\x00\x13\x00\x41\x00");
  978. printf("L2CAP send to %d returned %d\n",btm_fd,ret);
  979. bt_HCI_recv_ACL_async(btm_fd, &acldat);
  980. bt_HCI_recv_ACL_async(btm_fd, &acldat);
  981. memcpy(&dcid, &acldat.data[8], 2);
  982. memcpy(l2pkt, "\x04\x01\x04\x00\xAA\xAA\x00\x00", 8);
  983. memcpy(&l2pkt[4], &dcid, 2);
  984. ret = bt_L2CAP_send(btm_fd, chnd, 1, 8, l2pkt);
  985. printf("L2CAP send to %d returned %d\n",btm_fd,ret);
  986. bt_HCI_recv_ACL_async(btm_fd, &acldat);
  987. bt_HCI_recv_ACL_async(btm_fd, &acldat);
  988. memcpy(l2pkt, "\x05\x01\x06\x00\xAA\xAA\x00\x00\x00\x00", 10);
  989. memcpy(&l2pkt[4], &dcid, 2);
  990. ret = bt_L2CAP_send(btm_fd, chnd, 1, 10, l2pkt);
  991. printf("L2CAP send to %d returned %d\n",btm_fd,ret);
  992. while(true) {
  993. bt_HCI_recv_ACL_async(btm_fd, &acldat);
  994. checkAndReload();
  995. }
  996. }
  997. }
  998.  
  999.  
  1000. ret = IOS_Close(btm_fd);
  1001. printf("IOS close USB: %d\n",ret);
  1002.  
  1003. while(1) {
  1004. VIDEO_WaitVSync();
  1005. PAD_ScanPads();
  1006. int buttonsDown = PAD_ButtonsHeld(0);
  1007. if( (buttonsDown & PAD_TRIGGER_Z) && (buttonsDown & PAD_BUTTON_START)) {
  1008. loader();
  1009. }
  1010. }
  1011.  
  1012. return 0;
  1013. }
Add Comment
Please, Sign In to add comment