Advertisement
Guest User

Untitled

a guest
Jul 6th, 2015
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.39 KB | None | 0 0
  1. /* ultrasn0w (D) xerub 2014
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the "do What The Fuck you want to Public License";
  5. * either version 1 of the License, or whatever (the fuck) version you want.
  6. *
  7. * $ ios-clang -o ultrasn0w.o -Wno-variadic-macros -O2 -c ultrasn0w.c
  8. * $ ios-clang -o ultrasn0w.dylib -shared ultrasn0w.o -lsubstrate -lATCommandStudioDynamic
  9. *
  10. * Inject into CommCenterClassic iPhone3,1 baseband 1.59.00
  11. */
  12.  
  13.  
  14. #include <dlfcn.h>
  15. #include <fcntl.h>
  16. #include <pthread.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <sys/ioctl.h>
  20. #include <sys/utsname.h>
  21. #include <termios.h>
  22. #include <time.h>
  23. #include <unistd.h>
  24. #include <mach/mach_init.h>
  25. #include <mach/vm_map.h>
  26. #include <mach-o/getsect.h>
  27. #include <mach-o/dyld.h>
  28.  
  29. #define SPEED 115200
  30.  
  31. #define BUFSIZE (65536)
  32.  
  33. char *BasebandVersion(void);
  34. int atprog(const char *cmds[], int num);
  35. int my_open(const char *path, int flags, int mode);
  36. int $XLockHandler(int a1, const char **a2, int a3, int a4);
  37. int $InternalNotification(int a1, int a2, int a3, int a4, void *a5);
  38.  
  39. #define UDEBUG 1
  40. #define OPTION_USE_ATCSD_XLOCK 1
  41. #define OPTION_NO_TEMP_TIMEOUT 1 // XXX may be dangerous
  42. #define OPTION_USE_OTHER_LOWFD 0
  43. #define OPTION_ZAP_RESP_LENGTH 0
  44. #define OPTION_PATCH_XCGEDPAGE 1
  45. #define FW612 1
  46. #define FW704 1
  47. #define FW712 1
  48.  
  49. #define forever for (;;)
  50.  
  51. void MSHookFunction(vm_address_t addr, int (*f)(), void **pf);
  52.  
  53. #if UDEBUG
  54. char *timestamp(void);
  55. #define DBG(args...) do { fprintf(LogFile, args); fflush(LogFile); } while (0)
  56. static const char *
  57. noti(int a2)
  58. {
  59. static const char *names[] = {
  60. /* 0 */ "kEventCallActive",
  61. /* 1 */ "kEventCallInactive",
  62. /* 2 */ "kEventRegistered",
  63. /* 3 */ "kEventNotRegistered",
  64. /* 4 */ "kEventNewNetwork",
  65. /* 5 */ "kEventNewCell",
  66. /* 6 */ "kEventRadioOff",
  67. /* 7 */ "kEventRadioReset",
  68. /* 8 */ "kEventRadioOn",
  69. /* 9 */ "kEventRfDisabling",
  70. /* 10 */ "kEventRfDisabled",
  71. /* 11 */ "kEventSimDisabled",
  72. /* 12 */ "kEventSimUnreadable",
  73. /* 13 */ "kEventSimInitializing",
  74. /* 14 */ "kEventSimReady",
  75. /* 15 */ "kEventSimInitComplete",
  76. /* 16 */ "kEventIccidAvailable",
  77. /* 17 */ "kEventEnteringLowPower",
  78. /* 18 */ "kEventExitingLowPower",
  79. /* 19 */ "kEventSimRefresh",
  80. /* 20 */ "kEventSimFsRefresh",
  81. /* 21 */ "kEventDumpState",
  82. /* 22 */ "kEventManualSelectionDisabled",
  83. /* 23 */ "kEventHomePlmnUpdated",
  84. /* 24 */ "kEventPinBlocked",
  85. /* 25 */ "kEventPukBlocked",
  86. /* 26 */ "kEventNewOutgoingCallId",
  87. /* 27 */ "kEventSimPinEntryRequest",
  88. /* 28 */ "kEventSimPukEntryRequest",
  89. /* 29 */ "kEventSimPinAccessResponse",
  90. /* 30 */ "kEventSimPukAccessResponse",
  91. /* 31 */ "kEventEnteringBrickState",
  92. /* 32 */ "kEventExitingBrickState",
  93. /* 33 */ "kEventDataAttached",
  94. /* 34 */ "kEventDataNotAttached",
  95. /* 35 */ "kEventQuerySimStatus",
  96. /* 36 */ "kEventDataMode",
  97. /* 37 */ "kEventRadioMaxTxPower",
  98. /* 38 */ "kEventPdpContextActivated",
  99. /* 39 */ "kEventPdpContextDeactivated",
  100. /* 40 */ "kEventRAT",
  101. /* 41 */ "kEventPhoneNumberAvailable",
  102. /* 42 */ "kEventClearSimPIN",
  103. /* 43 */ "kEventSimType",
  104. /* 44 */ "kEventXSMSReady",
  105. /* 45 */ "kEventCallingLineIdRestrictionValueChanged",
  106. /* 46 */ "kEventOtaspCommitted",
  107. /* 47 */ "kEventECBMChanged",
  108. /* 48 */ "kEventEmergencyNumbersAvailbale",
  109. /* 49 */ "kEventNewCallinECBM",
  110. /* 50 */ "kEventECBMError",
  111. /* 51 */ "kEventFileTransferSuccessful",
  112. /* 52 */ "kEventFileTransferError",
  113. /* 53 */ "kEventSIMRefreshReceived",
  114. /* 54 */ "kEventServiceProvisionStateChanged",
  115. /* 55 */ "kEventActiveCallInSettingsModel",
  116. /* 56 */ "kEventCellularDataStatusAvailable"
  117. };
  118. int n = sizeof(names) / sizeof(names[0]);
  119. if (a2 >= 0 && a2 < n) {
  120. return names[a2];
  121. }
  122. return "???";
  123. }
  124. #else /* !UDEBUG */
  125. #define DBG(args...)
  126. #define noti(x) ""
  127. #endif /* !UDEBUG */
  128.  
  129. FILE *LogFile;
  130. vm_address_t XLockHandler;
  131. vm_address_t InternalNotification;
  132. int (*_XLockHandler)(int a1, const char **a2, int a3, int a4);
  133. int (*_InternalNotification)(int a1, int a2, int a3, int a4, void *a5);
  134. int (*_orig_open)(const char *pathname, int flags, mode_t mode);
  135. int fw;
  136. int lowFD;
  137. char readbuf[BUFSIZE];
  138. struct termios term;
  139.  
  140. const char *unlock_strings[4] = {
  141. "at+xapp=\"...................................."
  142. "\x88\x6a\xff\xed\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
  143. "\x2d\x7a\x01\x60\x22\x3b\x22\x58\x58\x34\x34\x34\x34\x35\x35\x35"
  144. "\x35\x36\x36\x36\x36\x37\x37\x37\x37\xf3\xa0\x14\x60\x55\x55\x55"
  145. "\x55\x07\x48\x80\x47\xd0\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  146. "\x55\x07\x1c\x0f\xbc\xd4\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  147. "\x55\xd2\x18\x07\x4b\xd8\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  148. "\x55\x98\x47\x38\x1c\xdc\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  149. "\x55\x04\x49\x88\x47\xe0\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  150. "\x55\x01\x49\x8d\x46\xe4\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  151. "\x55\x48\x1a\xf0\xbd\xe8\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  152. "\x55\x6c\x3c\x88\x72\xec\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  153. "\x55\x5c\x13\x18\x60\xf0\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  154. "\x55\x6c\x13\x18\x60\xf4\x1f\xff\xff\xf1\xa0\x14\x60\x55\x55\x55"
  155. "\x55\xfc\xd9\x1f\x60\xf8\x1f\xff\xff\xf1\xa0\x14\x60\x33\x33\x33"
  156. "\x33\x34\x34\x34\x34\x35\x35\x35\x35\xd1\x1f\xff\xff\xd0\x04\xff"
  157. "\xff\xbc\xa7\x87\x60\x59\x01\x01\x01\xff\xfe\xfe\xfe\x04\xf0\x1f"
  158. "\xe5\x34\x63\x73\x40\x0f\x48\x80\x38\x80\x38\x0f\x4a\x10\x60\xe4"
  159. "\x19\x0e\x48\x80\x47\x07\x1c\xaa\x19\x20\x25\x02\x35\x20\x78\xa8"
  160. "\x42\x09\xd0\xc0\x46\xff\x28\x02\xd1\x01\x34\x20\x78\x01\x30\x10"
  161. "\x70\x01\x34\x01\x32\xf2\xe7\x38\x1c\x05\x49\x88\x47\x48\x1a\x6a"
  162. "\x46\x12\x68\x10\x47\x1f\x01\xfa\x60\x80\x12\x70\x60\x5c\x13\x18"
  163. "\x60\x6c\x13\x18\x60\"",
  164.  
  165. "at+xapp=\"...................................."
  166. "\xdb\xa7\x88\x61\x01\x01\xfb\x61\xff\xfe\xfe\xfe\xff\xfe\xfe\xfe"
  167. "\xd9\x04\xff\xff\x5d\x6e\x18\x60\x22\x3b\x22\xff\xff\xff\xff\x10"
  168. "\xff\xff\x45\xff\xfe\x10\xbd\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5"
  169. "\x05\x40\x2a\x80\x1c\xff\xff\x0c\xff\xff\x78\x47\xff\xff\x1c\x04"
  170. "\xf0\x1f\xe5\x1d\x40\x2a\x80\x80\xff\xff\xff\x21\xff\xff\x04\xf0"
  171. "\x1f\xe5\xff\xff\x6f\x73\x40\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5"
  172. "\xa1\x40\x2a\x80\x04\xf0\x1f\xe5\xf8\x6e\x73\x40\xf7\xff\xfe\xff"
  173. "\xfe\xea\xf2\xe7\xa4\xff\xff\xa6\xff\xff\x04\xf0\x1f\xe5\xff\x07"
  174. "\x6f\x73\x40\x04\xf0\x1f\xe5\x10\x6f\x73\x40\x04\xf0\x1f\xe5\x18"
  175. "\x6f\x73\x40\x04\xf0\x1f\xe5\x20\x6f\x73\x40\x04\xf0\x1f\xe5\x28"
  176. "\x6f\x73\x40\x04\xf0\x1f\xe5\x30\x6f\x73\x40\x04\xf0\x1f\xe5\x38"
  177. "\x6f\x73\x40\x04\xf0\x1f\xe5\x40\x6f\x73\x40\x04\xf0\x1f\xe5\x48"
  178. "\x6f\x73\x40\x04\xf0\x1f\xe5\x50\x6f\x73\x40\x04\xf0\x1f\xe5\x58"
  179. "\x6f\x73\x40\x04\xf0\x1f\xe5\x60\x6f\x73\x40\x04\xf0\x1f\xe5\x68"
  180. "\x6f\x73\x40\x04\xf0\x1f\xe5\x70\x6f\x73\x40\x04\xf0\x1f\xe5\x78"
  181. "\x6f\x73\x40\x04\xf0\x1f\xe5\x80\x6f\x73\x40\x04\xf0\x1f\xe5\x88"
  182. "\x6f\x73\x40\x04\xf0\x1f\xe5\x90\x6f\x73\x40\x04\xf0\x1f\xe5\x98"
  183. "\x6f\x73\x40\x04\xf0\x1f\xe5\xa0\x6f\x73\x40\x04\xff\xff\xff\xff"
  184. "\xea\x02\xe0\x4c\x01\x02\xff\xff\x0a\xe0\x50\x01\x20\xff\xff\x78"
  185. "\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x49\x41\x2a\x80\x04\xf0\x1f\xe5"
  186. "\xa8\x6f\x73\x40\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xb1\x6f\x73"
  187. "\x40\x44\x03\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x45"
  188. "\x43\x2a\x80\x54\x03\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f"
  189. "\xe5\xb9\x71\x73\x40\x20\x04\x0c\xff\xff\x78\x47\xff\xff\x1c\x04"
  190. "\xf0\x1f\xe5\x21\x44\x2a\x80\xa4\x04\x0c\xff\xff\x78\x47\xff\xff"
  191. "\x1c\x04\xf0\x1f\xe5\x09\x73\x73\x40\xb4\x04\x0c\xff\xff\x78\x47"
  192. "\xff\xff\x1c\x04\xf0\x1f\xe5\xb5\x44\x2a\x80\x3c\x05\x0c\xff\xff"
  193. "\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x3d\x45\x2a\x80\x5c\x05\x0e"
  194. "\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x6d\x45\x2a\x80\xff"
  195. "\x07\xe0\x6c\x05\x02\xff\xff\xf6\xe7\x70\x05\x18\xff\xff\x78\x47"
  196. "\xff\xff\x1c\x04\xf0\x1f\xe5\x71\x45\x2a\x80\x78\x47\xff\xff\x1c"
  197. "\x04\xf0\x1f\xe5\x69\x45\x2a\x80\xf0\x06\x0c\xff\xff\x78\x47\xff"
  198. "\xff\x1c\x04\xf0\x1f\xe5\x55\x75\x73\x40\x34\x07\x0c\xff\xff\x78"
  199. "\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x35\x47\x2a\x80\x5c\x07\x0c\xff"
  200. "\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x5d\x47\x2a\x80\xc0\x07"
  201. "\x10\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xcd\x47\x2a\x80"
  202. "\xff\xff\x20\x70\x47\xd4\x07\x0c\xff\xff\x78\x47\xff\xff\x1c\x04"
  203. "\xf0\x1f\xe5\x39\x76\x73\x40\x88\xff\x07\x0c\xff\xff\x78\x47\xff"
  204. "\xff\x1c\x04\xf0\x1f\xe5\xed\x76\x73\x40\xcc\xff\x07\x0c\xff\xff"
  205. "\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xcd\x48\x2a\x80\xec\xff\x07"
  206. "\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x51\x77\x73\x40"
  207. "\xb4\x09\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x19\x78"
  208. "\x73\x40\xb4\x0a\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5"
  209. "\xb5\x4a\x2a\x80\x18\x0b\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0"
  210. "\x1f\xe5\x7d\x79\x73\x40\x6c\x0b\x18\xff\xff\x78\x47\xff\xff\x1c"
  211. "\x04\xf0\x1f\xe5\x6d\x4b\x2a\x80\x78\x47\xff\xff\x1c\x04\xf0\x1f"
  212. "\xe5\x79\x4b\x2a\x80\xe4\x0b\x0c\xff\xff\x78\x47\xff\xff\x1c\x04"
  213. "\xf0\x1f\xe5\xe5\x4b\x2a\x80\xbc\xff\x0c\x18\xff\xff\x78\x47\xff"
  214. "\xff\x1c\x04\xf0\x1f\xe5\x21\x7c\x73\x40\x78\x47\xff\xff\x1c\x04"
  215. "\xf0\x1f\xe5\x2d\x7c\x73\x40\x64\x0e\x0c\xff\xff\x78\x47\xff\xff"
  216. "\x1c\x04\xf0\x1f\xe5\xc9\x7c\x73\x40\xdc\x0e\x0c\xff\xff\x78\x47"
  217. "\xff\xff\x1c\x04\xf0\x1f\xe5\xdd\x4e\x2a\x80\xec\x0e\x0c\xff\xff"
  218. "\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xfb\x4e\x2a\x80\xfa\x0e\x02"
  219. "\xff\xff\xf7\xe7\x04\x0f\x0e\xff\xff\x78\x47\xff\xff\x1c\x04\xf0"
  220. "\x1f\xe5\x75\x7d\x73\x40\xf8\xe7\x18\x0f\x0c\xff\xff\x78\x47\xff"
  221. "\xff\x1c\x04\xf0\x1f\xe5\x19\x4f\x2a\x80\x2e\x0f\x0e\xff\xff\xff"
  222. "\xfe\xe7\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x2f\x4f\x2a\x80\x4c"
  223. "\x0f\x0c\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x4d\x4f\"",
  224.  
  225. "at+xapp=\"...................................."
  226. "\xdb\xa7\x88\x61\x27\x04\xfb\x61\xff\xfe\xfe\xfe\xff\xfe\xfe\xfe"
  227. "\xd9\x04\xff\xff\x5d\x6e\x18\x60\x22\x3b\x22\x2a\x80\x6a\x0f\x0e"
  228. "\xff\xff\xff\xfe\xe7\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\x6b\x4f"
  229. "\x2a\x80\x7c\x0f\x0e\xff\xff\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5"
  230. "\x89\x4f\x2a\x80\xf8\xe7\x92\x0f\x0e\xff\xff\xff\xfe\xe7\x78\x47"
  231. "\xff\xff\x1c\x04\xf0\x1f\xe5\x93\x4f\x2a\x80\xa4\x0f\x24\xff\xff"
  232. "\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xff\xfe\x4f\x2a\x80\x78\x47"
  233. "\xff\xff\x1c\x04\xf0\x1f\xe5\xb1\x4f\x2a\x80\x78\x47\xff\xff\x1c"
  234. "\x04\xf0\x1f\xe5\x21\x7e\x73\x40\xce\x0f\x0e\xff\xff\xff\xfe\xe7"
  235. "\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xcf\x4f\x2a\x80\xe6\x0f\x0e"
  236. "\xff\xff\xff\xfe\xe7\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xe7\x4f"
  237. "\x2a\x80\xfe\x0f\x02\xff\xff\xd1\xe7\xff\xff\xff\xff\xff\xff\xff"
  238. "\xff\"",
  239.  
  240. "at+xapp=\"...................................."
  241. "\xdb\xa7\x88\x61\x9b\x0a\x01\x01\xff\xfe\xfd\xfe\xff\xfe\xfe\xfe"
  242. "\xd9\x04\xff\xff\xa9\x09\xff\xff\x22\x3b\x22\xff\xff\x1c\x78\x47"
  243. "\xff\xff\x1c\x04\xf0\x1f\xe5\xff\xfe\x67\x73\x40\xf0\xb4\xff\xff"
  244. "\xf0\x59\xf8\x58\x48\x58\x49\xff\xff\xf0\x64\xf8\x5d\x4c\x5b\x4d"
  245. "\x60\x4e\xff\xff\x2e\x09\xd0\x60\x19\xff\xff\xf0\x86\xf8\x57\x49"
  246. "\x21\x43\x01\x60\x54\x48\x24\x18\x36\x1a\xf3\xe7\x5b\x4c\x20\x1c"
  247. "\xff\xff\xf0\x7b\xf8\xff\xff\x68\x21\x1c\xff\xff\xf0\x7c\xf8\x21"
  248. "\x1c\x1f\x31\x01\x60\x40\xa3\x98\x47\x20\x1c\x53\x49\x09\xff\x0c"
  249. "\x09\x05\x1f\x31\x49\x4b\x47\x4d\xff\xff\x2b\x04\xd0\x01\x60\x5b"
  250. "\x1b\x49\x19\x04\x30\xf8\xe7\x4d\x48\xff\xff\xf0\x61\xf8\x09\x34"
  251. "\x04\x60\x20\x1c\x4a\x49\xff\xff\xf0\x60\xf8\x3c\x49\x1f\x31\x01"
  252. "\x60\x32\xa3\x98\x47\x46\x48\x3f\x49\x09\x18\xff\xff\xf0\x27\xf8"
  253. "\x46\x4c\x47\x4d\x36\x4e\x28\x88\x6a\x88\x17\x1c\xff\xff\x2a\x05"
  254. "\xd0\x04\x35\x29\x1c\x80\x19\xa0\x47\xed\x19\xf4\xe7\x44\x48\x41"
  255. "\xa1\x0c\xff\x21\xa0\x47\xff\xff\xf0\x0e\xf8\xf0\xbc\xff\xff\x20"
  256. "\x3a\x4b\x18\x47\xff\xff\xb5\x26\x48\x80\x47\x27\xa1\xff\x07\x60"
  257. "\xc0\x21\xff\x07\x43\x24\x49\x88\x47\xff\xff\xbd\xff\xff\xb5\x23"
  258. "\x48\x21\x49\x88\x47\xff\xff\xbd\xf0\xb5\x81\xb0\x05\x1c\x0e\x1c"
  259. "\x21\x4f\x3f\x68\x1f\x4c\x24\x68\xff\xff\x20\xff\xff\x90\xb8\x42"
  260. "\x0b\xd0\xe0\x68\x21\x69\x2a\x1c\x33\x1c\xff\xff\xf0\xff\x07\xf8"
  261. "\x8c\x20\x24\x58\xff\xff\x98\x01\x30\xff\xff\x90\xf1\xe7\x01\xb0"
  262. "\xf0\xbd\x30\xb5\x12\x0b\x88\x42\x0a\xd2\x04\x68\x24\x0b\x94\x42"
  263. "\x04\xd1\x04\x68\x24\x05\x24\xff\x0c\xe4\x18\x04\x60\x04\x30\xf2"
  264. "\xe7\x30\xbd\x02\xff\x0c\x92\xff\xff\x11\x4b\xd0\x18\x70\x47\x80"
  265. "\x0a\x80\x02\x09\x0b\xff\xfe\x23\x19\x40\x89\xff\xff\xff\x07\x43"
  266. "\x70\x47\x17\x0f\xff\x07\xee\x16\x0f\xff\x07\xee\xff\x14\x0f\xff"
  267. "\x07\xee\x1e\xff\xfe\x2f\xe1\x18\xb0\x38\x60\x6c\x13\x18\x60\xff"
  268. "\xfe\xff\xfe\xff\xfe\xff\xfe\x18\xff\x21\xff\xfe\xff\xfe\x1c\xff"
  269. "\x21\xff\xfe\xff\xfe\xff\xff\x10\xff\xfe\xff\xfe\x64\x6e\x73\x40"
  270. "\xff\xff\x10\xff\xff\xff\xff\xff\xff\xff\xff\x09\xff\xff\xff\xff"
  271. "\xff\xff\x10\xff\xff\x0e\x04\xff\x07\xff\xff\xff\xff\xff\xff\xff"
  272. "\xff\x20\xff\xff\xff\xff\xff\xff\x60\x54\x63\x48\x60\xb0\xec\x83"
  273. "\x60\x10\x2a\xff\xfe\xff\xfe\xff\xff\xff\xff\xff\xff\x10\xff\xff"
  274. "\x40\x2a\x60\xff\xff\xe0\xf9\x60\x5d\x6e\x18\x60\xfc\xd9\x1f\x60"
  275. "\xff\xff\xff\xff\xfa\x60\x78\x47\xff\xff\x1c\x04\xf0\x1f\xe5\xdd"
  276. "\x6d\x73\x40\x78\x0f\xff\xfe\xff\xfe\""
  277. };
  278.  
  279. const char *activation_ticket[6] = {
  280. "at+xlck=0",
  281.  
  282. "at+xlck=1,1,\"000000000000000000000000000000000000000000000000"
  283. "0000000000000000000000000000000000000000000000000000000000000000"
  284. "0000000000000000000000000000000000000000000000000000000000000000"
  285. "0000000000000000000000000000000000000000000000000000000000000000"
  286. "0000000000000000000000000000000000000000000000000000000000000000"
  287. "0000000000000000000000000000000000000000000000000000000000000000"
  288. "0000000000000000000000000000000000000000000000000000000000000000"
  289. "0000000000000000000000000000000000000000000000000000000000000000"
  290. "0000000000000000\"",
  291.  
  292. "at+xlck=1,2,\"000000000000000000000000000000000000000000000000"
  293. "0000000000000000000000000000000000000000000000000000000000000000"
  294. "0000000000000000000000000000000000000000000000000000000000000000"
  295. "0000000000000000000000000000000000000000000000000000000000000000"
  296. "0000000000000000000000000000000000000000000000000000000000000000"
  297. "0000000000000000000000000000000000000000000000000000000000000000"
  298. "0000000000000000000000000000000000000000000000000000000000000000"
  299. "0000000000000000000000000000000000000000000000000000000000000000"
  300. "0000000000000000\"",
  301.  
  302. "at+xlck=1,3,\"000000000000000000000000000000000000000000000000"
  303. "0000000000000000000000000000000000000000000000000000000000000000"
  304. "0000000000000000000000000000000000000000000000000000000000000000"
  305. "0000000000000000000000000000000000000000000000000000000000000000"
  306. "0000000000000000000000000000000000000000000000000000000000000000"
  307. "0000000000000000000000000000000000000000000000000000000000000000"
  308. "0000000000000000000000000000000000000000000000000000000000000000"
  309. "0000000000000000000000000000000000000000000000000000000000000000"
  310. "0000000000000000\"",
  311.  
  312. "at+xlck=1,4,\"000000000000000000000000000000000000000000000000"
  313. "0000000000000000000000000000000000000000000000000000000000000000"
  314. "0000000000000000000000000000000000000000000000000000000000000000"
  315. "0000000000000000000000000000000000000000000000000000000000000000"
  316. "0000000000000000000000000000000000000000000000000000000000000000"
  317. "0000000000000000000000000000000000000000000000000000000000000000"
  318. "0000000000000000000000000000000000000000000000000000000000000000"
  319. "0000000000000000000000000000000000000000000000000000000000000000"
  320. "0000000000000000\"",
  321.  
  322. "at+xlck=2"
  323. };
  324.  
  325. int IsCompatible = -1;
  326. pthread_mutex_t at_mutex = PTHREAD_MUTEX_INITIALIZER;
  327. unsigned slide = 0;
  328. int debug = 1;
  329.  
  330. kern_return_t
  331. writeWord(vm_address_t addr, uint16_t val, int exec)
  332. {
  333. vm_prot_t new_protection;
  334.  
  335. unsigned pagesize = getpagesize();
  336. mach_port_t port = mach_task_self();
  337.  
  338. DBG("%s writeWord %x at %x/%x\n", timestamp(), val, addr - slide, addr);
  339. if (vm_protect(port, addr / pagesize * pagesize, pagesize, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY)) {
  340. return 1;
  341. }
  342. *(uint16_t *)addr = val;
  343. if (exec) {
  344. new_protection = VM_PROT_READ | VM_PROT_EXECUTE;
  345. } else {
  346. new_protection = VM_PROT_READ;
  347. }
  348. if (vm_protect(port, addr / pagesize * pagesize, pagesize, 0, new_protection)) {
  349. return 1;
  350. }
  351. DBG("%s writeWord ok: %x\n", timestamp(), *(uint16_t *)addr);
  352. return 0;
  353. }
  354.  
  355. vm_address_t
  356. FindLastThumbFunction(vm_address_t addr)
  357. {
  358. uint16_t *ptr, *p;
  359. unsigned int size;
  360.  
  361. if (slide) {
  362. ptr = (uint16_t *)(getsectdata("__TEXT", "__text", (unsigned long *)&size) + slide);
  363. } else {
  364. ptr = (uint16_t *)getsectdatafromheader((struct mach_header *)0x1000, "__TEXT", "__text", &size);
  365. }
  366. p = (uint16_t *)(addr & ~3);
  367. while (--p >= (uint16_t *)ptr) {
  368. if ((p[0] & 0xFF00) == 0xB500 && (p[-1] & 0xF000) != 0xF000) {
  369. return (vm_address_t)p + 1;
  370. }
  371. }
  372. return 0;
  373. }
  374.  
  375. vm_address_t
  376. FindReference(vm_address_t addr)
  377. {
  378. char *ptr, *end;
  379. unsigned int size;
  380.  
  381. if (slide) {
  382. ptr = getsectdata("__TEXT", "__text", (unsigned long *)&size) + slide;
  383. } else {
  384. ptr = getsectdatafromheader((struct mach_header *)0x1000, "__TEXT", "__text", &size);
  385. }
  386.  
  387. end = ptr + size - 4;
  388.  
  389. if (!addr) {
  390. return 0;
  391. }
  392.  
  393. for (; ptr < end; ptr++) {
  394. if (!memcmp(ptr, &addr, 4)) {
  395. return (vm_address_t)ptr;
  396. }
  397. }
  398.  
  399. if (addr == 0xAFBB8) {
  400. return 0x55230;
  401. }
  402. if (addr == 0xA8E3C) {
  403. return 0x2AE8C;
  404. }
  405.  
  406. #define SLIDE(a, x) if (addr == slide + (a)) return (x) + slide
  407. switch (fw) {
  408. case 431:
  409. SLIDE(0xF47AC, 0x6039C);
  410. SLIDE(0xED6C0, 0x34114);
  411. SLIDE(0xF02EC, 0x458B4);
  412. break;
  413. case 432:
  414. SLIDE(0xF47AC, 0x60370);
  415. SLIDE(0xED6C0, 0x340E8);
  416. SLIDE(0xF02EC, 0x45888);
  417. break;
  418. case 433:
  419. SLIDE(0xF4738, 0x6030C);
  420. SLIDE(0xED64C, 0x34110);
  421. SLIDE(0xF0278, 0x45824);
  422. break;
  423. case 500:
  424. SLIDE(0x124DD5, 0x680B4);
  425. SLIDE(0x11CEC9, 0x35704);
  426. SLIDE(0x11FEA1, 0x4BB24);
  427. break;
  428. case 501:
  429. SLIDE(0x124DD0, 0x67B54);
  430. SLIDE(0x11CE6C, 0x34FA8);
  431. SLIDE(0x11FE60, 0x4B504);
  432. break;
  433. case 51:
  434. SLIDE(0x117DC8, 0x6B754);
  435. SLIDE(0x10FCB0, 0x38820);
  436. SLIDE(0x112CBD, 0x4EF0C);
  437. break;
  438. case 511:
  439. SLIDE(0x117BF8, 0x6B2C0);
  440. SLIDE(0x10FAE0, 0x3838C);
  441. SLIDE(0x112AED, 0x4EA78);
  442. break;
  443. #if FW612
  444. case 612:
  445. SLIDE(0x1D0834, 0xAB308);
  446. SLIDE(0x1C813F, 0x56B1A);
  447. SLIDE(0x1CB735, 0x7DABC);
  448. #if OPTION_NO_TEMP_TIMEOUT
  449. SLIDE(0x1CE4E9, 0xA39DE);
  450. #endif
  451. break;
  452. #endif
  453. #if FW704
  454. case 704:
  455. SLIDE(0x2E917E, 0x12C0AE);
  456. SLIDE(0x2DF714, 0x8C852);
  457. SLIDE(0x2E3373, 0xBF360);
  458. #if OPTION_NO_TEMP_TIMEOUT
  459. SLIDE(0x2E6D99, 0x122A4E);
  460. #endif
  461. break;
  462. #endif
  463. #if FW712
  464. case 712:
  465. SLIDE(0x2FB767, 0x13216E);
  466. SLIDE(0x2F1CA5, 0x808D6);
  467. SLIDE(0x2F5938, 0xB49F8);
  468. #if OPTION_NO_TEMP_TIMEOUT
  469. SLIDE(0x2F9382, 0x128B7E);
  470. #endif
  471. break;
  472. #endif
  473. }
  474. #undef SLIDE
  475. return 0;
  476. }
  477.  
  478. vm_address_t
  479. FindString(const char *str)
  480. {
  481. char *ptr, *end;
  482. unsigned int size;
  483.  
  484. if (slide) {
  485. ptr = getsectdata("__TEXT", "__cstring", (unsigned long *)&size) + slide;
  486. } else {
  487. ptr = getsectdatafromheader((struct mach_header *)0x1000, "__TEXT", "__cstring", &size);
  488. }
  489. for (end = ptr + size - strlen(str); ptr < end; ptr++) {
  490. if (!strcmp(ptr, str)) {
  491. return (vm_address_t)ptr;
  492. }
  493. }
  494. return 0;
  495. }
  496.  
  497. char *
  498. FindStringN(const char *str, size_t n)
  499. {
  500. char *ptr;
  501. char *end;
  502. unsigned int size;
  503.  
  504. if (slide) {
  505. ptr = getsectdata("__TEXT", "__cstring", (unsigned long *)&size) + slide;
  506. } else {
  507. ptr = getsectdatafromheader((struct mach_header *)0x1000, "__TEXT", "__cstring", &size);
  508. }
  509. for (end = ptr + size - strlen(str); ptr < end; ptr++) {
  510. if (!strncmp(ptr, str, n)) {
  511. return ptr;
  512. }
  513. }
  514. return NULL;
  515. }
  516.  
  517. char *
  518. timestamp(void)
  519. {
  520. static char buf[32];
  521. time_t t = time(NULL);
  522. #if UDEBUG
  523. int len = sprintf(buf, "%u", getpid());
  524. buf[len++] = ' ';
  525. ctime_r(&t, buf + len);
  526. buf[len + 24] = '\0';
  527. #else
  528. ctime_r(&t, buf);
  529. buf[24] = '\0';
  530. #endif
  531. return buf;
  532. }
  533.  
  534. void __attribute__((constructor))
  535. Start(void)
  536. {
  537. struct utsname buf;
  538. vm_address_t addr;
  539.  
  540. memset(&buf, 0, sizeof(buf));
  541. uname(&buf);
  542. if (strcmp("iPhone3,1", buf.machine)) {
  543. dlopen("/usr/share/ultrasn0w/ultrasn0w-xgold608.dylib", RTLD_LAZY | RTLD_GLOBAL);
  544. return;
  545. }
  546.  
  547. LogFile = fopen("/var/wireless/Library/Logs/ultrasn0w-dylib.log", "w");
  548. DBG("==================================================================== %u\n", getpid());
  549. fprintf(LogFile, "%s ultrasn0w loaded via CommCenter\n", timestamp());
  550. fflush(LogFile);
  551.  
  552. slide = _dyld_get_image_vmaddr_slide(0);
  553.  
  554. addr = FindString("+xsimstate=1") - slide;
  555. if (FindStringN("Mar 18 2011", 11)) {
  556. fw = 431;
  557. }
  558. if (FindStringN("Apr 4 2011", 11)) {
  559. fw = 432;
  560. }
  561. if (FindStringN("Apr 28 2011", 11)) {
  562. fw = 433;
  563. }
  564.  
  565. if (addr == 0x11CF51) {
  566. fw = 500;
  567. } else if (addr == 0x11CEF4) {
  568. fw = 501;
  569. } else if (addr == 0x10FD38) {
  570. fw = 51;
  571. } else if (addr == 0x10FB68) {
  572. fw = 511;
  573. #if FW612
  574. } else if (addr == 0x1C81C7) {
  575. fw = 612;
  576. #endif
  577. #if FW704
  578. } else if (addr == 0x2DF79C) {
  579. fw = 704;
  580. #endif
  581. #if FW712
  582. } else if (addr == 0x2F1D2D) {
  583. fw = 712;
  584. #endif
  585. }
  586. DBG("%s fw = %d\n", timestamp(), fw);
  587.  
  588. addr = FindReference(FindString("+xcgedpage=0,1"));
  589. if (addr) {
  590. addr = FindLastThumbFunction(addr);
  591. DBG("%s xcged = %x/%x\n", timestamp(), addr - slide, addr);
  592. if (*(uint16_t *)(addr + 15) == 0xB183) {
  593. writeWord(addr + 15, 0xE010, 1);
  594. } else if (*(uint16_t *)(addr + 23) == 0xD017) {
  595. writeWord(addr + 23, 0xE017, 1);
  596. #if OPTION_PATCH_XCGEDPAGE
  597. #if FW612
  598. } else if (*(uint16_t *)(addr + 23) == 0xD018) {
  599. writeWord(addr + 23, 0xE018, 1);
  600. #endif
  601. #if FW704 || FW712
  602. } else if (*(uint16_t *)(addr + 19) == 0xB1C1) {
  603. writeWord(addr + 19, 0xE018, 1);
  604. #endif
  605. #endif /* OPTION_PATCH_XCGEDPAGE */
  606. }
  607. }
  608.  
  609. #if OPTION_NO_TEMP_TIMEOUT && (FW612 || FW704 || FW712)
  610. addr = FindReference(FindString("+xdrv=5,16,%d"));
  611. if (addr) {
  612. addr = FindLastThumbFunction(addr);
  613. DBG("%s xdrv5 = %x/%x\n", timestamp(), addr - slide, addr);
  614. if (0) {
  615. #if FW612
  616. } else if (*(uint16_t *)(addr + 19) == 0x2D01) {
  617. writeWord(addr + 19, 0x2DFF, 1);
  618. #endif
  619. #if FW704 || FW712
  620. } else if (*(uint16_t *)(addr + 23) == 0x2D01) {
  621. writeWord(addr + 23, 0x2DFF, 1);
  622. #endif
  623. }
  624. }
  625. #endif /* OPTION_NO_TEMP_TIMEOUT */
  626.  
  627. addr = FindReference(FindString("Sending internal notification %s (%d) params={%d, %d, %p}\n"));
  628. if (addr) {
  629. InternalNotification = FindLastThumbFunction(addr);
  630. DBG("%s InternalNotification = %x/%x\n", timestamp(), InternalNotification - slide, InternalNotification);
  631. addr = FindReference(FindString("activation ticket accepted... drive thru\n"));
  632. if (addr) {
  633. XLockHandler = FindLastThumbFunction(addr);
  634. DBG("%s XLockHandler = %x/%x\n", timestamp(), XLockHandler - slide, XLockHandler);
  635. MSHookFunction(InternalNotification, $InternalNotification, (void **)&_InternalNotification);
  636. MSHookFunction(XLockHandler, $XLockHandler, (void **)&_XLockHandler);
  637. MSHookFunction((vm_address_t)open, my_open, (void **)&_orig_open);
  638. fprintf(LogFile, "%s ultrasn0w hooked\n", timestamp());
  639. fflush(LogFile);
  640. }
  641. }
  642. }
  643.  
  644. int
  645. my_open(const char *path, int flags, int mode)
  646. {
  647. int fd = _orig_open(path, flags, mode);
  648. if (!strcmp(path, "/dev/dlci.spi-baseband.low")) {
  649. DBG("%s my_open(%s, 0x%x, 0%o)\n", timestamp(), path, flags, mode);
  650. if (fw == 431
  651. #if OPTION_USE_OTHER_LOWFD
  652. || fw == 612 // XXX 612?
  653. || fw == 704 // XXX 704?
  654. || fw == 712 // XXX 712?
  655. #endif
  656. ) {
  657. lowFD = _orig_open("/dev/dlci.spi-baseband.extra_0", flags, 0); // XXX mode?
  658. } else {
  659. lowFD = fd;
  660. }
  661. DBG("%s lowFD = %d\n", timestamp(), lowFD);
  662. }
  663. return fd;
  664. }
  665.  
  666. #if OPTION_USE_ATCSD_XLOCK
  667. bool _ZNK10ATResponse14isFieldPresentEiib(void *this, int index, int, bool);
  668. void _ZNK10ATResponse22getStringFieldInternalENS_11FieldFormatEiii(void *out, void *this, int/*format?*/, int index, int, int);
  669. int _ZNK10ATResponse11getIntFieldEiii(void *this, int index, int, int base);
  670. #endif
  671.  
  672. int
  673. $XLockHandler(int a1, const char **a2, int a3, int a4)
  674. {
  675. pthread_mutex_lock(&at_mutex);
  676. DBG("%s XLockHandler= %p %p %p %p %p %p\n", timestamp(), a2[0], a2[1], a2[2], a2[3], a2[4], a2[5]);
  677. {
  678. #if OPTION_USE_ATCSD_XLOCK
  679. bool present = _ZNK10ATResponse14isFieldPresentEiib(a2, 0, 0, false);
  680. DBG("%s XLockHandler: isFieldPresent: %d\n", timestamp(), present);
  681. if (present) {
  682. int i;
  683. for (i = 0; _ZNK10ATResponse14isFieldPresentEiib(a2, i + 2, 0, false); i += 3) {
  684. char out[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  685. _ZNK10ATResponse22getStringFieldInternalENS_11FieldFormatEiii(out, a2, 0, i, 0, 0);
  686. if (out) {
  687. int v7 = _ZNK10ATResponse11getIntFieldEiii(a2, i + 1, 0, 10);
  688. int v4 = _ZNK10ATResponse11getIntFieldEiii(a2, i + 2, 0, 10);
  689. if (out[0] == 4 && out[1] == 'P' && out[2] == 'N' && out[3] == '\0') {
  690. DBG("%s XLockHandler: PN %d %d\n", timestamp(), v7, v4);
  691. if (IsCompatible && v7 == 1 && v4 == 1) {
  692. DBG("%s XLockHandler: activation_ticket\n", timestamp());
  693. write(lowFD, "at+xpow=1\r", 10);
  694. atprog(activation_ticket, 6);
  695. write(lowFD, "at+xpow=0\r", 10);
  696. }
  697. }
  698. }
  699. }
  700. }
  701. #else /* !OPTION_USE_ATCSD_XLOCK */
  702. const char *const *p2 = a2;
  703. #if 1 /* XXX higher FWs need this? */
  704. if (p2[0] < (char *)0x1000 || p2[0] >= (char *)0x40000000) {
  705. p2 += 2;
  706. if (p2[0] < (char *)0x1000 || p2[0] >= (char *)0x40000000) {
  707. p2 += 2;
  708. if (p2[0] < (char *)0x1000 || p2[0] >= (char *)0x40000000) {
  709. goto done;
  710. }
  711. }
  712. }
  713. #endif
  714. DBG("%s XLockHandler: %s\n", timestamp(), p2[0]);
  715. if (IsCompatible == 1 && strstr(p2[0], "+XLOCK: \"PN\",1,1")) {
  716. DBG("%s XLockHandler: activation_ticket\n", timestamp());
  717. write(lowFD, "at+xpow=1\r", 10);
  718. atprog(activation_ticket, 6);
  719. write(lowFD, "at+xpow=0\r", 10);
  720. }
  721. done:;
  722. #endif /* !OPTION_USE_ATCSD_XLOCK */
  723. }
  724. pthread_mutex_unlock(&at_mutex);
  725. return _XLockHandler(a1, a2, a3, a4);
  726. }
  727.  
  728. int
  729. CheckCompatibility(void)
  730. {
  731. const char *version;
  732. int i = 0;
  733. int retries = (fw >= 500) ? 2 : 5;
  734.  
  735. forever {
  736. version = BasebandVersion();
  737. if (version && *version) {
  738. break;
  739. }
  740. if (++i >= retries) {
  741. if (version && *version) {
  742. break;
  743. }
  744. if (fw >= 500) {
  745. fprintf(LogFile, "%s Unable to query baseband version...will assume it's compatible\n", timestamp());
  746. return 1;
  747. }
  748. fprintf(LogFile, "%s Unable to query baseband version...will assume it's NOT compatible\n", timestamp());
  749. return 0;
  750. }
  751. }
  752. if (!strcmp(version, "01.59.00")) {
  753. return 1;
  754. }
  755. fprintf(LogFile, "%s ERROR! %s works only for baseband \"%s\", but this baseband is \"%s\"\n", "ultrasn0w", timestamp(), "01.59.00", version);
  756. return 0;
  757. }
  758.  
  759. int
  760. $InternalNotification(int a1, int a2, int a3, int a4, void *a5)
  761. {
  762. pthread_mutex_lock(&at_mutex);
  763. DBG("%s InternalNotification(%d:%s, %d, %d, %p)\n", timestamp(), a2, noti(a2), a3, a4, a5);
  764. if (a2 == 7) {
  765. write(lowFD, "at+xpow=1\r", 10);
  766. fprintf(LogFile, "%s Baseband reset!\n", timestamp());
  767. fflush(LogFile);
  768. if (IsCompatible == -1) {
  769. IsCompatible = CheckCompatibility();
  770. }
  771. if (IsCompatible == 1) {
  772. fprintf(LogFile, "%s Unlocking!\n", timestamp());
  773. fflush(LogFile);
  774. atprog(unlock_strings, 4);
  775. fprintf(LogFile, "%s Unlocking commands sent!\n", timestamp());
  776. fflush(LogFile);
  777. }
  778. write(lowFD, "at+xpow=0\r", 10);
  779. }
  780. pthread_mutex_unlock(&at_mutex);
  781. return _InternalNotification(a1, a2, a3, a4, a5);
  782. }
  783.  
  784. int
  785. InitConn(speed_t speed)
  786. {
  787. int handshake = TIOCM_DSR | TIOCM_CTS | TIOCM_RTS | TIOCM_DTR;
  788. int blahnull = 0;
  789. int fd = open("/dev/tty.debug", O_NOCTTY | O_RDWR);
  790. if (fd == -1) {
  791. perror("open");
  792. exit(1);
  793. }
  794. ioctl(fd, TIOCEXCL);
  795. fcntl(fd, F_SETFL, 0);
  796. tcgetattr(fd, (struct termios *)&term);
  797. ioctl(fd, _IOW('T', 10, int), &blahnull);
  798. cfsetspeed((struct termios *)&term, speed);
  799. cfmakeraw((struct termios *)&term);
  800. term.c_cc[VTIME] = 5;
  801. term.c_iflag = (term.c_iflag & ~(ICRNL | IXON | IXOFF | IXANY | INPCK | ISTRIP | IGNBRK | BRKINT | IGNPAR)) | IGNPAR | IGNBRK;
  802. term.c_cc[VMIN] = 0;
  803. term.c_oflag &= ~OPOST;
  804. term.c_cflag = (term.c_cflag & ~PARENB) | CS8;
  805. term.c_lflag &= ~(IEXTEN | ICANON | ISIG | ECHO);
  806. tcsetattr(fd, TCSANOW, &term);
  807. ioctl(fd, TIOCSDTR);
  808. ioctl(fd, TIOCCDTR);
  809. ioctl(fd, TIOCMSET, &handshake);
  810. return fd;
  811. }
  812.  
  813. int
  814. ReadResp(int fd, unsigned int timeout_sec, unsigned int timeout_micro)
  815. {
  816. struct timeval timeout;
  817. struct timeval *to;
  818. fd_set readfds;
  819. int nfds;
  820. int len = 0;
  821.  
  822. nfds = fd + 1;
  823.  
  824. FD_ZERO(&readfds);
  825. FD_SET(fd, &readfds);
  826.  
  827. timeout.tv_sec = timeout_sec;
  828. timeout.tv_usec = timeout_micro;
  829.  
  830. if (timeout.tv_sec || timeout.tv_usec) {
  831. to = &timeout;
  832. } else {
  833. to = NULL;
  834. }
  835.  
  836. do {
  837. if (select(nfds, &readfds, NULL, NULL, to) <= 0) {
  838. #if OPTION_ZAP_RESP_LENGTH
  839. len = 0;
  840. #endif
  841. break;
  842. }
  843. len += read(fd, readbuf + len, BUFSIZE - len);
  844. readbuf[len] = '\0';
  845. DBG("%s we have read (%d) %.*s\n", timestamp(), len, 16, readbuf);
  846. if (strstr(readbuf, "\r\nOK\r\n")) {
  847. break;
  848. }
  849. } while (!strstr(readbuf, "\r\nERROR\r\n"));
  850. return len;
  851. }
  852.  
  853. ssize_t
  854. SendCmd(int fd, const void *cmd, size_t size)
  855. {
  856. return (write(fd, cmd, size) == -1) ? -1 : 0;
  857. }
  858.  
  859. ssize_t
  860. SendStrCmd(int fd, const char *cmd)
  861. {
  862. return SendCmd(fd, cmd, strlen(cmd));
  863. }
  864.  
  865. ssize_t
  866. SendAT(int fd)
  867. {
  868. return SendStrCmd(fd, "AT\r");
  869. }
  870.  
  871. int
  872. AT(int fd)
  873. {
  874. int i;
  875.  
  876. SendAT(fd);
  877. i = 0;
  878. do {
  879. if (ReadResp(fd, 0, 500000)) {
  880. return 1;
  881. }
  882. i++;
  883. SendAT(fd);
  884. } while (i != 15);
  885. return 0;
  886. }
  887.  
  888. int
  889. lockcheck(void)
  890. {
  891. int fd;
  892. int len;
  893.  
  894. fd = InitConn(SPEED);
  895. AT(fd);
  896. forever {
  897. forever {
  898. SendStrCmd(fd, "at+cpin?\r");
  899. len = ReadResp(fd, 0, 100000);
  900. if (len > 0) {
  901. break;
  902. }
  903. AT(fd);
  904. AT(fd);
  905. }
  906. readbuf[len] = 0;
  907. fprintf(LogFile, "%s\n", readbuf);
  908. fflush(LogFile);
  909. if (strstr(readbuf, "PH-NET")) {
  910. close(fd);
  911. return 1;
  912. }
  913. if (strstr(readbuf, "OK")) {
  914. break;
  915. }
  916. sleep(1);
  917. }
  918. close(fd);
  919. return 0;
  920. }
  921.  
  922. int
  923. pincheck(void)
  924. {
  925. int fd;
  926. int len;
  927.  
  928. fd = InitConn(SPEED);
  929. AT(fd);
  930. forever {
  931. do {
  932. forever {
  933. SendStrCmd(fd, "at+cpin?\r");
  934. len = ReadResp(fd, 0, 100000);
  935. if (len > 0) {
  936. break;
  937. }
  938. AT(fd);
  939. AT(fd);
  940. }
  941. readbuf[len] = 0;
  942. } while (strstr(readbuf, "SIM PIN"));
  943. if (strstr(readbuf, "OK")) {
  944. break;
  945. }
  946. sleep(1);
  947. }
  948. close(fd);
  949. return 0;
  950. }
  951.  
  952. int
  953. atping(void)
  954. {
  955. int fd;
  956.  
  957. fd = InitConn(SPEED);
  958. AT(fd);
  959. return close(fd);
  960. }
  961.  
  962. char *
  963. BasebandVersion(void)
  964. {
  965. static char ret[16];
  966.  
  967. int retry;
  968. int fd;
  969. int len;
  970. char *p, *ptr;
  971.  
  972. retry = 0;
  973. ret[15] = '\0';
  974. ret[0] = '\0';
  975. fd = InitConn(SPEED);
  976. AT(fd);
  977. do {
  978. SendStrCmd(fd, "AT+XGENDATA\r");
  979. len = ReadResp(fd, 0, 100000);
  980. if (len) {
  981. if (len > 0) {
  982. ptr = strstr(readbuf, "ICE3_MODEM_");
  983. if (ptr) {
  984. strncpy(ret, ptr + 11, 15);
  985. for (p = ret; *p; p++) {
  986. if (*p == '_') {
  987. *p = '\0';
  988. break;
  989. }
  990. }
  991. break;
  992. }
  993. } else {
  994. AT(fd);
  995. }
  996. }
  997. } while (++retry != 50);
  998. close(fd);
  999. DBG("%s BasebandVersion got [%s]\n", timestamp(), ret);
  1000. return ret;
  1001. }
  1002.  
  1003. int
  1004. atprog(const char *cmds[], int num)
  1005. {
  1006. int i, j;
  1007. int fd;
  1008.  
  1009. fd = InitConn(SPEED);
  1010. if (!AT(fd)) {
  1011. return -1;
  1012. }
  1013. for (i = 0; i < num; i++) {
  1014. DBG("%s atprog -> %.*s\n", timestamp(), 16, cmds[i]);
  1015. int txlen;
  1016. char *buf = malloc(strlen(cmds[i]) + 7);
  1017. strcpy(buf, cmds[i]);
  1018. txlen = strlen(buf);
  1019. if (buf[txlen - 1] == '\n') {
  1020. buf[txlen - 1] = '\0';
  1021. }
  1022. strcat(buf, "\r");
  1023. txlen = strlen(buf);
  1024. if (txlen) {
  1025. j = 0;
  1026. forever {
  1027. DBG("%s atprog... send\n", timestamp());
  1028. SendStrCmd(fd, buf);
  1029. if (ReadResp(fd, 0, 100000) > 0)
  1030. break;
  1031. DBG("%s atprog... RETRY\n", timestamp());
  1032. AT(fd);
  1033. ++j;
  1034. AT(fd);
  1035. if (j == 51)
  1036. {
  1037. DBG("%s atprog... TIMEOUT?\n", timestamp());
  1038. goto done;
  1039. }
  1040. }
  1041. free(buf);
  1042. }
  1043. }
  1044. done:
  1045. close(fd);
  1046. return 0;
  1047. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement