libusbmuxd.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817
  1. /*
  2. * libusbmuxd.c
  3. *
  4. * Copyright (C) 2009-2019 Nikias Bassen <nikias@gmx.li>
  5. * Copyright (C) 2009-2014 Martin Szulecki <m.szulecki@libimobiledevice.org>
  6. * Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <stdint.h>
  26. #include <stdlib.h>
  27. #include <errno.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #ifdef LIBUSBMUXD_STATIC
  31. #define USBMUXD_API
  32. #elif defined(_WIN32)
  33. #define USBMUXD_API __declspec( dllexport )
  34. #else
  35. #if __GNUC__ >= 4
  36. #define USBMUXD_API __attribute__((visibility("default")))
  37. #else
  38. #define USBMUXD_API
  39. #endif
  40. #endif
  41. #ifndef EPROTO
  42. #define EPROTO 134
  43. #endif
  44. #ifndef EBADMSG
  45. #define EBADMSG 104
  46. #endif
  47. #ifndef ECONNREFUSED
  48. #define ECONNREFUSED 107
  49. #endif
  50. #ifdef _WIN32
  51. #include <winsock2.h>
  52. #include <windows.h>
  53. #define sleep(x) Sleep(x*1000)
  54. #else
  55. #include <unistd.h>
  56. #include <signal.h>
  57. #include <sys/socket.h>
  58. #include <arpa/inet.h>
  59. #if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) && !defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME_ERRNO_H)
  60. extern char *program_invocation_short_name;
  61. #endif
  62. #ifdef __APPLE__
  63. extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize);
  64. #include <sys/stat.h>
  65. #endif
  66. #endif
  67. #ifdef HAVE_INOTIFY
  68. #include <sys/inotify.h>
  69. #include <sys/select.h>
  70. #include <pthread.h>
  71. #define EVENT_SIZE (sizeof (struct inotify_event))
  72. #define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
  73. #define USBMUXD_DIRNAME "/var/run"
  74. #define USBMUXD_SOCKET_NAME "usbmuxd"
  75. static int use_inotify = 1;
  76. #endif /* HAVE_INOTIFY */
  77. #ifndef HAVE_STPNCPY
  78. static char* stpncpy(char *dst, const char *src, size_t len)
  79. {
  80. size_t n = strlen(src);
  81. if (n > len)
  82. n = len;
  83. return strncpy(dst, src, len) + n;
  84. }
  85. #endif
  86. #ifdef _MSC_VER
  87. #define strcasecmp _stricmp
  88. #endif
  89. #include <plist/plist.h>
  90. #define PLIST_LIBUSBMUX_VERSION 3
  91. static char *bundle_id = NULL;
  92. static char *prog_name = NULL;
  93. // usbmuxd public interface
  94. #include "usbmuxd.h"
  95. // usbmuxd protocol
  96. #include "usbmuxd-proto.h"
  97. // socket utility functions
  98. #include <libimobiledevice-glue/socket.h>
  99. // misc utility functions
  100. #include <libimobiledevice-glue/collection.h>
  101. // threads
  102. #include <libimobiledevice-glue/thread.h>
  103. static int libusbmuxd_debug = 0;
  104. #ifndef PACKAGE
  105. #define PACKAGE "libusbmuxd"
  106. #endif
  107. #ifndef PACKAGE_NAME
  108. #define PACKAGE_NAME PACKAGE
  109. #endif
  110. #define LIBUSBMUXD_DEBUG(level, format, ...) if (level <= libusbmuxd_debug) fprintf(stderr, ("[" PACKAGE "] " format), __VA_ARGS__); fflush(stderr);
  111. #define LIBUSBMUXD_ERROR(format, ...) LIBUSBMUXD_DEBUG(0, format, __VA_ARGS__)
  112. static struct collection devices;
  113. static THREAD_T devmon = THREAD_T_NULL;
  114. static int listenfd = -1;
  115. static int running = 0;
  116. static int cancelling = 0;
  117. static volatile int use_tag = 0;
  118. static volatile int proto_version = 1;
  119. static volatile int try_list_devices = 1;
  120. struct usbmuxd_subscription_context {
  121. usbmuxd_event_cb_t callback;
  122. void *user_data;
  123. };
  124. static struct usbmuxd_subscription_context *event_ctx = NULL;
  125. static struct collection listeners;
  126. thread_once_t listener_init_once = THREAD_ONCE_INIT;
  127. mutex_t listener_mutex;
  128. /**
  129. * Finds a device info record by its handle.
  130. * if the record is not found, NULL is returned.
  131. */
  132. static usbmuxd_device_info_t *devices_find(uint32_t handle)
  133. {
  134. FOREACH(usbmuxd_device_info_t *dev, &devices) {
  135. if (dev && dev->handle == handle) {
  136. return dev;
  137. }
  138. } ENDFOREACH
  139. return NULL;
  140. }
  141. /**
  142. * Creates a socket connection to usbmuxd.
  143. * For Mac/Linux it is a unix domain socket,
  144. * for Windows it is a tcp socket.
  145. */
  146. static int connect_usbmuxd_socket()
  147. {
  148. int res = -1;
  149. char *usbmuxd_socket_addr = getenv("USBMUXD_SOCKET_ADDRESS");
  150. if (usbmuxd_socket_addr) {
  151. if (strncmp(usbmuxd_socket_addr, "UNIX:", 5) == 0) {
  152. #if defined(_WIN32) || defined(__CYGWIN__)
  153. /* not supported, ignore */
  154. #else
  155. if (usbmuxd_socket_addr[5] != '\0') {
  156. res = socket_connect_unix(usbmuxd_socket_addr+5);
  157. if (res < 0) {
  158. res = -errno;
  159. }
  160. return res;
  161. }
  162. #endif
  163. } else {
  164. uint16_t port = 0;
  165. char *p = strrchr(usbmuxd_socket_addr, ':');
  166. if (p) {
  167. char *endp = NULL;
  168. long l_port = strtol(p+1, &endp, 10);
  169. if (endp && *endp == '\0') {
  170. if (l_port > 0 && l_port < 65536) {
  171. port = (uint16_t)l_port;
  172. }
  173. }
  174. }
  175. if (p && port > 0) {
  176. char *connect_addr = NULL;
  177. if (usbmuxd_socket_addr[0] == '[') {
  178. connect_addr = strdup(usbmuxd_socket_addr+1);
  179. connect_addr[p - usbmuxd_socket_addr - 1] = '\0';
  180. p = strrchr(connect_addr, ']');
  181. if (p) {
  182. *p = '\0';
  183. }
  184. } else {
  185. connect_addr = strdup(usbmuxd_socket_addr);
  186. connect_addr[p - usbmuxd_socket_addr] = '\0';
  187. }
  188. if (connect_addr && *connect_addr != '\0') {
  189. res = socket_connect(connect_addr, port);
  190. #ifdef HAVE_INOTIFY
  191. use_inotify = 0;
  192. #endif
  193. free(connect_addr);
  194. if (res < 0) {
  195. res = -errno;
  196. }
  197. return res;
  198. }
  199. free(connect_addr);
  200. }
  201. }
  202. }
  203. #if defined(_WIN32) || defined(__CYGWIN__)
  204. res = socket_connect("127.0.0.1", USBMUXD_SOCKET_PORT);
  205. #else
  206. res = socket_connect_unix(USBMUXD_SOCKET_FILE);
  207. #endif
  208. if (res < 0) {
  209. res = -errno;
  210. }
  211. return res;
  212. }
  213. static void sanitize_udid(usbmuxd_device_info_t *devinfo)
  214. {
  215. if (!devinfo)
  216. return;
  217. if (strlen(devinfo->udid) == 24) {
  218. memmove(&devinfo->udid[9], &devinfo->udid[8], 17);
  219. devinfo->udid[8] = '-';
  220. }
  221. if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) {
  222. sprintf(devinfo->udid + 32, "%08x", devinfo->handle);
  223. }
  224. }
  225. static usbmuxd_device_info_t *device_info_from_plist(plist_t props)
  226. {
  227. usbmuxd_device_info_t* devinfo = NULL;
  228. plist_t n = NULL;
  229. uint64_t val = 0;
  230. char *strval = NULL;
  231. devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
  232. if (!devinfo)
  233. return NULL;
  234. memset(devinfo, 0, sizeof(usbmuxd_device_info_t));
  235. n = plist_dict_get_item(props, "DeviceID");
  236. if (n && plist_get_node_type(n) == PLIST_UINT) {
  237. plist_get_uint_val(n, &val);
  238. devinfo->handle = (uint32_t)val;
  239. }
  240. n = plist_dict_get_item(props, "ProductID");
  241. if (n && plist_get_node_type(n) == PLIST_UINT) {
  242. plist_get_uint_val(n, &val);
  243. devinfo->product_id = (uint32_t)val;
  244. }
  245. n = plist_dict_get_item(props, "SerialNumber");
  246. if (n && plist_get_node_type(n) == PLIST_STRING) {
  247. plist_get_string_val(n, &strval);
  248. if (strval) {
  249. char *t = stpncpy(devinfo->udid, strval, sizeof(devinfo->udid)-1);
  250. *t = '\0';
  251. sanitize_udid(devinfo);
  252. free(strval);
  253. }
  254. }
  255. n = plist_dict_get_item(props, "ConnectionType");
  256. if (n && plist_get_node_type(n) == PLIST_STRING) {
  257. plist_get_string_val(n, &strval);
  258. if (strval) {
  259. if (strcmp(strval, "USB") == 0) {
  260. devinfo->conn_type = CONNECTION_TYPE_USB;
  261. } else if (strcmp(strval, "Network") == 0) {
  262. devinfo->conn_type = CONNECTION_TYPE_NETWORK;
  263. n = plist_dict_get_item(props, "NetworkAddress");
  264. if (n && plist_get_node_type(n) == PLIST_DATA) {
  265. uint64_t addr_len = 0;
  266. const char *netaddr = plist_get_data_ptr(n, &addr_len);
  267. if (netaddr && addr_len > 0 && addr_len < sizeof(devinfo->conn_data)) {
  268. memcpy(devinfo->conn_data, netaddr, addr_len);
  269. }
  270. }
  271. } else {
  272. LIBUSBMUXD_ERROR("%s: Unexpected ConnectionType '%s'\n", __func__, strval);
  273. }
  274. free(strval);
  275. }
  276. }
  277. if (!devinfo->udid[0]) {
  278. LIBUSBMUXD_ERROR("%s: Failed to get SerialNumber (UDID)!\n", __func__);
  279. free(devinfo);
  280. return NULL;
  281. }
  282. if (!devinfo->conn_type) {
  283. LIBUSBMUXD_ERROR("%s: Failed to get ConnectionType!\n", __func__);
  284. free(devinfo);
  285. devinfo = NULL;
  286. } else if (devinfo->conn_type == CONNECTION_TYPE_NETWORK && !devinfo->conn_data[0]) {
  287. LIBUSBMUXD_ERROR("%s: Failed to get EscapedFullServiceName!\n", __func__);
  288. free(devinfo);
  289. devinfo = NULL;
  290. }
  291. return devinfo;
  292. }
  293. static usbmuxd_device_info_t *device_info_from_device_record(struct usbmuxd_device_record *dev)
  294. {
  295. if (!dev) {
  296. return NULL;
  297. }
  298. usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
  299. if (!devinfo) {
  300. LIBUSBMUXD_ERROR("%s: Out of memory while allocating device info object\n", __func__);
  301. return NULL;
  302. }
  303. devinfo->handle = dev->device_id;
  304. devinfo->product_id = dev->product_id;
  305. char *t = stpncpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)-2);
  306. *t = '\0';
  307. sanitize_udid(devinfo);
  308. return devinfo;
  309. }
  310. static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload, int timeout)
  311. {
  312. int recv_len;
  313. struct usbmuxd_header hdr;
  314. char *payload_loc = NULL;
  315. header->length = 0;
  316. header->version = 0;
  317. header->message = 0;
  318. header->tag = 0;
  319. recv_len = socket_receive_timeout(sfd, &hdr, sizeof(hdr), 0, timeout);
  320. if (recv_len < 0) {
  321. if (!cancelling) {
  322. LIBUSBMUXD_DEBUG(1, "%s: Error receiving packet: %s\n", __func__, strerror(-recv_len));
  323. }
  324. return recv_len;
  325. }
  326. if ((size_t)recv_len < sizeof(hdr)) {
  327. LIBUSBMUXD_DEBUG(1, "%s: Received packet is too small, got %d bytes!\n", __func__, recv_len);
  328. return recv_len;
  329. }
  330. uint32_t payload_size = hdr.length - sizeof(hdr);
  331. if (payload_size > 0) {
  332. payload_loc = (char*)malloc(payload_size);
  333. uint32_t rsize = 0;
  334. do {
  335. int res = socket_receive_timeout(sfd, payload_loc + rsize, payload_size - rsize, 0, 5000);
  336. if (res < 0) {
  337. break;
  338. }
  339. rsize += res;
  340. } while (rsize < payload_size);
  341. if (rsize != payload_size) {
  342. LIBUSBMUXD_DEBUG(1, "%s: Error receiving payload of size %d (bytes received: %d)\n", __func__, payload_size, rsize);
  343. free(payload_loc);
  344. return -EBADMSG;
  345. }
  346. }
  347. if (hdr.message == MESSAGE_PLIST) {
  348. char *message = NULL;
  349. plist_t plist = NULL;
  350. plist_from_xml(payload_loc, payload_size, &plist);
  351. free(payload_loc);
  352. if (!plist) {
  353. LIBUSBMUXD_DEBUG(1, "%s: Error getting plist from payload!\n", __func__);
  354. return -EBADMSG;
  355. }
  356. plist_t node = plist_dict_get_item(plist, "MessageType");
  357. if (!node || plist_get_node_type(node) != PLIST_STRING) {
  358. *payload = plist;
  359. hdr.length = sizeof(hdr);
  360. memcpy(header, &hdr, sizeof(hdr));
  361. return hdr.length;
  362. }
  363. plist_get_string_val(node, &message);
  364. if (message) {
  365. uint64_t val = 0;
  366. if (strcmp(message, "Result") == 0) {
  367. /* result message */
  368. uint32_t dwval = 0;
  369. plist_t n = plist_dict_get_item(plist, "Number");
  370. plist_get_uint_val(n, &val);
  371. *payload = malloc(sizeof(uint32_t));
  372. dwval = val;
  373. memcpy(*payload, &dwval, sizeof(dwval));
  374. hdr.length = sizeof(hdr) + sizeof(dwval);
  375. hdr.message = MESSAGE_RESULT;
  376. } else if (strcmp(message, "Attached") == 0) {
  377. /* device add message */
  378. usbmuxd_device_info_t *devinfo = NULL;
  379. plist_t props = plist_dict_get_item(plist, "Properties");
  380. if (!props) {
  381. LIBUSBMUXD_DEBUG(1, "%s: Could not get properties for message '%s' from plist!\n", __func__, message);
  382. free(message);
  383. plist_free(plist);
  384. return -EBADMSG;
  385. }
  386. devinfo = device_info_from_plist(props);
  387. if (!devinfo) {
  388. LIBUSBMUXD_DEBUG(1, "%s: Could not create device info object from properties!\n", __func__);
  389. free(message);
  390. plist_free(plist);
  391. return -EBADMSG;
  392. }
  393. *payload = (void*)devinfo;
  394. hdr.length = sizeof(hdr) + sizeof(usbmuxd_device_info_t);
  395. hdr.message = MESSAGE_DEVICE_ADD;
  396. } else if (strcmp(message, "Detached") == 0) {
  397. /* device remove message */
  398. uint32_t dwval = 0;
  399. plist_t n = plist_dict_get_item(plist, "DeviceID");
  400. if (n) {
  401. plist_get_uint_val(n, &val);
  402. *payload = malloc(sizeof(uint32_t));
  403. dwval = val;
  404. memcpy(*payload, &dwval, sizeof(dwval));
  405. hdr.length = sizeof(hdr) + sizeof(dwval);
  406. hdr.message = MESSAGE_DEVICE_REMOVE;
  407. }
  408. } else if (strcmp(message, "Paired") == 0) {
  409. /* device pair message */
  410. uint32_t dwval = 0;
  411. plist_t n = plist_dict_get_item(plist, "DeviceID");
  412. if (n) {
  413. plist_get_uint_val(n, &val);
  414. *payload = malloc(sizeof(uint32_t));
  415. dwval = val;
  416. memcpy(*payload, &dwval, sizeof(dwval));
  417. hdr.length = sizeof(hdr) + sizeof(dwval);
  418. hdr.message = MESSAGE_DEVICE_PAIRED;
  419. }
  420. } else {
  421. char *xml = NULL;
  422. uint32_t len = 0;
  423. plist_to_xml(plist, &xml, &len);
  424. LIBUSBMUXD_DEBUG(1, "%s: Unexpected message '%s' in plist:\n%s\n", __func__, message, xml);
  425. free(xml);
  426. free(message);
  427. plist_free(plist);
  428. return -EBADMSG;
  429. }
  430. free(message);
  431. }
  432. plist_free(plist);
  433. } else if (hdr.message == MESSAGE_DEVICE_ADD) {
  434. usbmuxd_device_info_t *devinfo = device_info_from_device_record((struct usbmuxd_device_record*)payload_loc);
  435. free(payload_loc);
  436. *payload = devinfo;
  437. } else {
  438. *payload = payload_loc;
  439. }
  440. memcpy(header, &hdr, sizeof(hdr));
  441. return hdr.length;
  442. }
  443. /**
  444. * Retrieves the result code to a previously sent request.
  445. */
  446. static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result, void **result_plist)
  447. {
  448. struct usbmuxd_header hdr;
  449. int recv_len;
  450. uint32_t *res = NULL;
  451. if (!result) {
  452. return -EINVAL;
  453. }
  454. *result = -1;
  455. if (result_plist) {
  456. *result_plist = NULL;
  457. }
  458. recv_len = receive_packet(sfd, &hdr, (void**)&res, 5000);
  459. if (recv_len < 0 || (size_t)recv_len < sizeof(hdr)) {
  460. free(res);
  461. return (recv_len < 0 ? recv_len : -EPROTO);
  462. }
  463. if (hdr.message == MESSAGE_RESULT) {
  464. int ret = 0;
  465. if (hdr.tag != tag) {
  466. LIBUSBMUXD_DEBUG(1, "%s: WARNING: tag mismatch (%d != %d). Proceeding anyway.\n", __func__, hdr.tag, tag);
  467. }
  468. if (res) {
  469. memcpy(result, res, sizeof(uint32_t));
  470. ret = 1;
  471. }
  472. free(res);
  473. return ret;
  474. }
  475. if (hdr.message == MESSAGE_PLIST) {
  476. if (!result_plist) {
  477. LIBUSBMUXD_DEBUG(1, "%s: MESSAGE_PLIST result but result_plist pointer is NULL!\n", __func__);
  478. return -1;
  479. }
  480. *result_plist = (plist_t)res;
  481. *result = RESULT_OK;
  482. return 1;
  483. }
  484. LIBUSBMUXD_DEBUG(1, "%s: Unexpected message of type %d received!\n", __func__, hdr.message);
  485. free(res);
  486. return -EPROTO;
  487. }
  488. static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, uint32_t payload_size)
  489. {
  490. struct usbmuxd_header header;
  491. header.length = sizeof(struct usbmuxd_header);
  492. header.version = proto_version;
  493. header.message = message;
  494. header.tag = tag;
  495. if (payload && (payload_size > 0)) {
  496. header.length += payload_size;
  497. }
  498. int sent = socket_send(sfd, &header, sizeof(header));
  499. if (sent != sizeof(header)) {
  500. LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send packet header\n", __func__);
  501. return -1;
  502. }
  503. if (payload && (payload_size > 0)) {
  504. uint32_t ssize = 0;
  505. do {
  506. int res = socket_send(sfd, (char*)payload + ssize, payload_size - ssize);
  507. if (res < 0) {
  508. break;
  509. }
  510. ssize += res;
  511. } while (ssize < payload_size);
  512. sent += ssize;
  513. }
  514. if (sent != (int)header.length) {
  515. LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send whole packet (sent %d of %d)\n", __func__, sent, header.length);
  516. socket_close(sfd);
  517. return -1;
  518. }
  519. return sent;
  520. }
  521. static int send_plist_packet(int sfd, uint32_t tag, plist_t message)
  522. {
  523. int res;
  524. char *payload = NULL;
  525. uint32_t payload_size = 0;
  526. plist_to_xml(message, &payload, &payload_size);
  527. res = send_packet(sfd, MESSAGE_PLIST, tag, payload, payload_size);
  528. free(payload);
  529. return res;
  530. }
  531. static void get_bundle_id()
  532. {
  533. #if defined (__APPLE__)
  534. char CONTENTS_INFO_PLIST[] = "Contents/Info.plist";
  535. char* execpath = malloc(1024);
  536. uint32_t size = 1024;
  537. if (_NSGetExecutablePath(execpath, &size) != 0) {
  538. free(execpath);
  539. return;
  540. }
  541. // strip off executable name
  542. char *p = execpath + strlen(execpath) - 1;
  543. while (p > execpath && *p != '/') p--;
  544. if (*p == '/') *p = '\0';
  545. // now walk back trying to find "/Contents/MacOS", and strip it off
  546. int macos_found = 0;
  547. while (p > execpath) {
  548. p--;
  549. if (*p != '/') continue;
  550. if (strcmp(p, "/.") == 0) {
  551. *p = '\0';
  552. } else if (!macos_found && strcmp(p, "/MacOS") == 0) {
  553. *p = '\0';
  554. macos_found++;
  555. } else if (macos_found && strcmp(p, "/Contents") == 0) {
  556. *p = '\0';
  557. break;
  558. } else {
  559. break;
  560. }
  561. }
  562. // now just append "/Contents/Info.plist"
  563. size_t len = strlen(execpath) + sizeof(CONTENTS_INFO_PLIST) + 1;
  564. char *infopl = malloc(len);
  565. snprintf(infopl, len, "%s/%s", execpath, CONTENTS_INFO_PLIST);
  566. free(execpath);
  567. struct stat fst;
  568. fst.st_size = 0;
  569. if (stat(infopl, &fst) != 0) {
  570. free(infopl);
  571. return;
  572. }
  573. size_t fsize = fst.st_size;
  574. if (fsize < 8) {
  575. free(infopl);
  576. return;
  577. }
  578. FILE *f = fopen(infopl, "r");
  579. free(infopl);
  580. if (!f)
  581. return;
  582. char *buf = malloc(fsize);
  583. if (!buf)
  584. return;
  585. if (fread(buf, 1, fsize, f) == fsize) {
  586. plist_t pl = NULL;
  587. if (memcmp(buf, "bplist00", 8) == 0) {
  588. plist_from_bin(buf, fst.st_size, &pl);
  589. } else {
  590. plist_from_xml(buf, fst.st_size, &pl);
  591. }
  592. if (pl) {
  593. plist_t bid = plist_dict_get_item(pl, "CFBundleIdentifier");
  594. if (plist_get_node_type(bid) == PLIST_STRING) {
  595. plist_get_string_val(bid, &bundle_id);
  596. }
  597. plist_free(pl);
  598. }
  599. }
  600. free(buf);
  601. fclose(f);
  602. #endif
  603. }
  604. static void get_prog_name()
  605. {
  606. #if defined(__APPLE__) || defined(__FreeBSD__)
  607. const char *pname = getprogname();
  608. if (pname) {
  609. prog_name = strdup(pname);
  610. }
  611. #elif defined (_WIN32)
  612. TCHAR *_pname = malloc((MAX_PATH+1) * sizeof(TCHAR));
  613. if (GetModuleFileName(NULL, _pname, MAX_PATH+1) > 0) {
  614. char* pname = NULL;
  615. #if defined(UNICODE) || defined(_UNICODE)
  616. char* __pname = NULL;
  617. int l = WideCharToMultiByte(CP_UTF8, 0, _pname, -1, NULL, 0, NULL, NULL);
  618. if (l > 0) {
  619. __pname = malloc(l);
  620. if (WideCharToMultiByte(CP_UTF8, 0, _pname, -1, __pname, l, NULL, NULL) > 0) {
  621. pname = __pname;
  622. }
  623. }
  624. #else
  625. pname = _pname;
  626. #endif
  627. if (pname) {
  628. char *p = pname+strlen(pname)-1;
  629. while (p > pname && *p != '\\' && *p != '/') p--;
  630. if (*p == '\\' || *p == '/') p++;
  631. prog_name = strdup(p);
  632. }
  633. #if defined(UNICODE) || defined(_UNICODE)
  634. free(__pname);
  635. #endif
  636. }
  637. free(_pname);
  638. #elif defined (HAVE_PROGRAM_INVOCATION_SHORT_NAME)
  639. char *pname = program_invocation_short_name;
  640. if (pname) {
  641. prog_name = strdup(pname);
  642. }
  643. #elif defined (__linux__)
  644. FILE *f = fopen("/proc/self/stat", "r");
  645. if (!f) {
  646. return;
  647. }
  648. char *tmpbuf = malloc(512);
  649. size_t r = fread(tmpbuf, 1, 512, f);
  650. if (r > 0) {
  651. char *p = tmpbuf;
  652. while (((size_t)(p-tmpbuf) < r) && (*p != '(') && (*p != '\0')) p++;
  653. if (*p == '(') {
  654. p++;
  655. char *pname = p;
  656. while (((size_t)(p-tmpbuf) < r) && (*p != ')') && (*p != '\0')) p++;
  657. if (*p == ')') {
  658. *p = '\0';
  659. prog_name = strdup(pname);
  660. }
  661. }
  662. }
  663. free(tmpbuf);
  664. fclose(f);
  665. #else
  666. #warning FIXME: no method to determine program name
  667. #endif
  668. }
  669. static plist_t create_plist_message(const char* message_type)
  670. {
  671. char client_version[128];
  672. snprintf(client_version, 128, PACKAGE_NAME " %s", libusbmuxd_version());
  673. if (!bundle_id) {
  674. get_bundle_id();
  675. }
  676. if (!prog_name) {
  677. get_prog_name();
  678. }
  679. plist_t plist = plist_new_dict();
  680. if (bundle_id) {
  681. plist_dict_set_item(plist, "BundleID", plist_new_string(bundle_id));
  682. }
  683. plist_dict_set_item(plist, "ClientVersionString", plist_new_string(client_version));
  684. plist_dict_set_item(plist, "MessageType", plist_new_string(message_type));
  685. if (prog_name) {
  686. plist_dict_set_item(plist, "ProgName", plist_new_string(prog_name));
  687. }
  688. plist_dict_set_item(plist, "kLibUSBMuxVersion", plist_new_uint(PLIST_LIBUSBMUX_VERSION));
  689. return plist;
  690. }
  691. static int send_listen_packet(int sfd, uint32_t tag)
  692. {
  693. int res = 0;
  694. if (proto_version == 1) {
  695. /* construct message plist */
  696. plist_t plist = create_plist_message("Listen");
  697. res = send_plist_packet(sfd, tag, plist);
  698. plist_free(plist);
  699. } else {
  700. /* binary packet */
  701. res = send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0);
  702. }
  703. return res;
  704. }
  705. static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port)
  706. {
  707. int res = 0;
  708. if (proto_version == 1) {
  709. /* construct message plist */
  710. plist_t plist = create_plist_message("Connect");
  711. plist_dict_set_item(plist, "DeviceID", plist_new_uint(device_id));
  712. plist_dict_set_item(plist, "PortNumber", plist_new_uint(htons(port)));
  713. res = send_plist_packet(sfd, tag, plist);
  714. plist_free(plist);
  715. } else {
  716. /* binary packet */
  717. struct {
  718. uint32_t device_id;
  719. uint16_t port;
  720. uint16_t reserved;
  721. } conninfo;
  722. conninfo.device_id = device_id;
  723. conninfo.port = htons(port);
  724. conninfo.reserved = 0;
  725. res = send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo));
  726. }
  727. return res;
  728. }
  729. static int send_list_devices_packet(int sfd, uint32_t tag)
  730. {
  731. int res = -1;
  732. /* construct message plist */
  733. plist_t plist = create_plist_message("ListDevices");
  734. res = send_plist_packet(sfd, tag, plist);
  735. plist_free(plist);
  736. return res;
  737. }
  738. static int send_read_buid_packet(int sfd, uint32_t tag)
  739. {
  740. int res = -1;
  741. /* construct message plist */
  742. plist_t plist = create_plist_message("ReadBUID");
  743. res = send_plist_packet(sfd, tag, plist);
  744. plist_free(plist);
  745. return res;
  746. }
  747. static int send_pair_record_packet(int sfd, uint32_t tag, const char* msgtype, const char* pair_record_id, uint32_t device_id, plist_t data)
  748. {
  749. int res = -1;
  750. /* construct message plist */
  751. plist_t plist = create_plist_message(msgtype);
  752. plist_dict_set_item(plist, "PairRecordID", plist_new_string(pair_record_id));
  753. if (data) {
  754. plist_dict_set_item(plist, "PairRecordData", plist_copy(data));
  755. }
  756. if (device_id > 0) {
  757. plist_dict_set_item(plist, "DeviceID", plist_new_uint(device_id));
  758. }
  759. res = send_plist_packet(sfd, tag, plist);
  760. plist_free(plist);
  761. return res;
  762. }
  763. /**
  764. * Generates an event, i.e. calls the callback function.
  765. * A reference to a populated usbmuxd_event_t with information about the event
  766. * and the corresponding device will be passed to the callback function.
  767. */
  768. static void generate_event(const usbmuxd_device_info_t *dev, enum usbmuxd_event_type event)
  769. {
  770. usbmuxd_event_t ev;
  771. if (!dev) {
  772. return;
  773. }
  774. ev.event = event;
  775. memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));
  776. mutex_lock(&listener_mutex);
  777. FOREACH(struct usbmuxd_subscription_context* context, &listeners) {
  778. context->callback(&ev, context->user_data);
  779. } ENDFOREACH
  780. mutex_unlock(&listener_mutex);
  781. }
  782. static int usbmuxd_listen_poll()
  783. {
  784. int sfd;
  785. sfd = connect_usbmuxd_socket();
  786. if (sfd < 0) {
  787. while (1) {
  788. mutex_lock(&listener_mutex);
  789. int num = collection_count(&listeners);
  790. mutex_unlock(&listener_mutex);
  791. if (num <= 0) {
  792. break;
  793. }
  794. if ((sfd = connect_usbmuxd_socket()) >= 0) {
  795. break;
  796. }
  797. sleep(1);
  798. }
  799. }
  800. return sfd;
  801. }
  802. #ifdef HAVE_INOTIFY
  803. #ifndef HAVE_PSELECT
  804. static int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask)
  805. {
  806. int ready;
  807. struct timeval tv;
  808. struct timeval *p_timeout;
  809. sigset_t origmask;
  810. if (timeout) {
  811. tv.tv_sec = timeout->tv_sec;
  812. tv.tv_usec = timeout->tv_nsec / 1000;
  813. p_timeout = &tv;
  814. } else {
  815. p_timeout = NULL;
  816. }
  817. pthread_sigmask(SIG_SETMASK, sigmask, &origmask);
  818. ready = select(nfds, readfds, writefds, exceptfds, p_timeout);
  819. pthread_sigmask(SIG_SETMASK, &origmask, NULL);
  820. return ready;
  821. }
  822. #endif
  823. static int usbmuxd_listen_inotify()
  824. {
  825. int inot_fd;
  826. int watch_d;
  827. int sfd;
  828. if (!use_inotify) {
  829. return -2;
  830. }
  831. sfd = connect_usbmuxd_socket();
  832. if (sfd >= 0)
  833. return sfd;
  834. sfd = -1;
  835. inot_fd = inotify_init1(IN_CLOEXEC);
  836. if (inot_fd < 0) {
  837. LIBUSBMUXD_DEBUG(1, "%s: Failed to setup inotify\n", __func__);
  838. return -2;
  839. }
  840. /* inotify is setup, listen for events that concern us */
  841. watch_d = inotify_add_watch (inot_fd, USBMUXD_DIRNAME, IN_CREATE);
  842. if (watch_d < 0) {
  843. LIBUSBMUXD_DEBUG(1, "%s: Failed to setup watch descriptor for socket dir\n", __func__);
  844. close (inot_fd);
  845. return -2;
  846. }
  847. while (1) {
  848. fd_set rfds;
  849. struct timespec tv = {1, 0};
  850. FD_ZERO(&rfds);
  851. FD_SET(inot_fd, &rfds);
  852. int r = pselect(inot_fd+1, &rfds, NULL, NULL, &tv, NULL);
  853. if (r < 0) {
  854. break;
  855. }
  856. if (r == 0) {
  857. continue;
  858. }
  859. ssize_t len, i;
  860. char buff[EVENT_BUF_LEN] = {0};
  861. i = 0;
  862. len = read (inot_fd, buff, EVENT_BUF_LEN -1);
  863. if (len < 0)
  864. goto end;
  865. while (i < len) {
  866. struct inotify_event *pevent = (struct inotify_event *) & buff[i];
  867. /* check that it's ours */
  868. if (pevent->mask & IN_CREATE &&
  869. pevent->len &&
  870. pevent->name[0] != 0 &&
  871. strcmp(pevent->name, USBMUXD_SOCKET_NAME) == 0) {
  872. /* retry if usbmuxd isn't ready yet */
  873. int retry = 10;
  874. while (--retry >= 0) {
  875. if ((sfd = connect_usbmuxd_socket ()) >= 0) {
  876. break;
  877. }
  878. sleep(1);
  879. }
  880. goto end;
  881. }
  882. i += EVENT_SIZE + pevent->len;
  883. }
  884. }
  885. end:
  886. inotify_rm_watch(inot_fd, watch_d);
  887. close(inot_fd);
  888. return sfd;
  889. }
  890. #endif /* HAVE_INOTIFY */
  891. /**
  892. * Tries to connect to usbmuxd and wait if it is not running.
  893. */
  894. static int usbmuxd_listen()
  895. {
  896. int sfd;
  897. uint32_t res = -1;
  898. int tag;
  899. retry:
  900. #ifdef HAVE_INOTIFY
  901. sfd = usbmuxd_listen_inotify();
  902. if (sfd == -2)
  903. sfd = usbmuxd_listen_poll();
  904. #else
  905. sfd = usbmuxd_listen_poll();
  906. #endif
  907. if (sfd < 0) {
  908. if (!cancelling) {
  909. LIBUSBMUXD_DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__);
  910. }
  911. return sfd;
  912. }
  913. tag = ++use_tag;
  914. if (send_listen_packet(sfd, tag) <= 0) {
  915. LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send listen packet\n", __func__);
  916. socket_close(sfd);
  917. return -1;
  918. }
  919. if ((usbmuxd_get_result(sfd, tag, &res, NULL) == 1) && (res != 0)) {
  920. socket_close(sfd);
  921. if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
  922. proto_version = 0;
  923. goto retry;
  924. }
  925. LIBUSBMUXD_DEBUG(1, "%s: ERROR: did not get OK but %d\n", __func__, res);
  926. return -1;
  927. }
  928. return sfd;
  929. }
  930. /**
  931. * Waits for an event to occur, i.e. a packet coming from usbmuxd.
  932. * Calls generate_event to pass the event via callback to the client program.
  933. */
  934. static int get_next_event(int sfd)
  935. {
  936. struct usbmuxd_header hdr;
  937. void *payload = NULL;
  938. /* block until we receive something */
  939. if (receive_packet(sfd, &hdr, &payload, 0) < 0) {
  940. if (!cancelling) {
  941. LIBUSBMUXD_DEBUG(1, "%s: Error in usbmuxd connection, disconnecting all devices!\n", __func__);
  942. }
  943. // when then usbmuxd connection fails,
  944. // generate remove events for every device that
  945. // is still present so applications know about it
  946. FOREACH(usbmuxd_device_info_t *dev, &devices) {
  947. generate_event(dev, UE_DEVICE_REMOVE);
  948. collection_remove(&devices, dev);
  949. free(dev);
  950. } ENDFOREACH
  951. return -EIO;
  952. }
  953. if ((hdr.length > sizeof(hdr)) && !payload) {
  954. LIBUSBMUXD_DEBUG(1, "%s: Invalid packet received, payload is missing!\n", __func__);
  955. return -EBADMSG;
  956. }
  957. if (hdr.message == MESSAGE_DEVICE_ADD) {
  958. usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)payload;
  959. collection_add(&devices, devinfo);
  960. generate_event(devinfo, UE_DEVICE_ADD);
  961. payload = NULL;
  962. } else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
  963. uint32_t handle;
  964. usbmuxd_device_info_t *devinfo;
  965. memcpy(&handle, payload, sizeof(uint32_t));
  966. devinfo = devices_find(handle);
  967. if (!devinfo) {
  968. LIBUSBMUXD_DEBUG(1, "%s: WARNING: got device remove message for handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle);
  969. } else {
  970. generate_event(devinfo, UE_DEVICE_REMOVE);
  971. collection_remove(&devices, devinfo);
  972. free(devinfo);
  973. }
  974. } else if (hdr.message == MESSAGE_DEVICE_PAIRED) {
  975. uint32_t handle;
  976. usbmuxd_device_info_t *devinfo;
  977. memcpy(&handle, payload, sizeof(uint32_t));
  978. devinfo = devices_find(handle);
  979. if (!devinfo) {
  980. LIBUSBMUXD_DEBUG(1, "%s: WARNING: got paired message for device handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle);
  981. } else {
  982. generate_event(devinfo, UE_DEVICE_PAIRED);
  983. }
  984. } else if (hdr.length > 0) {
  985. LIBUSBMUXD_DEBUG(1, "%s: Unexpected message type %d length %d received!\n", __func__, hdr.message, hdr.length);
  986. }
  987. free(payload);
  988. return 0;
  989. }
  990. static void device_monitor_cleanup(void* data)
  991. {
  992. FOREACH(usbmuxd_device_info_t *dev, &devices) {
  993. collection_remove(&devices, dev);
  994. free(dev);
  995. } ENDFOREACH
  996. collection_free(&devices);
  997. socket_close(listenfd);
  998. listenfd = -1;
  999. }
  1000. /**
  1001. * Device Monitor thread function.
  1002. *
  1003. * This function sets up a connection to usbmuxd
  1004. */
  1005. static void *device_monitor(void *data)
  1006. {
  1007. running = 1;
  1008. collection_init(&devices);
  1009. cancelling = 0;
  1010. #ifdef HAVE_THREAD_CLEANUP
  1011. thread_cleanup_push(device_monitor_cleanup, NULL);
  1012. #endif
  1013. do {
  1014. listenfd = usbmuxd_listen();
  1015. if (listenfd < 0) {
  1016. continue;
  1017. }
  1018. while (running) {
  1019. int res = get_next_event(listenfd);
  1020. if (res < 0) {
  1021. break;
  1022. }
  1023. }
  1024. mutex_lock(&listener_mutex);
  1025. if (collection_count(&listeners) == 0) {
  1026. running = 0;
  1027. }
  1028. mutex_unlock(&listener_mutex);
  1029. } while (running);
  1030. #ifdef HAVE_THREAD_CLEANUP
  1031. thread_cleanup_pop(1);
  1032. #else
  1033. device_monitor_cleanup(NULL);
  1034. #endif
  1035. return NULL;
  1036. }
  1037. static void init_listeners(void)
  1038. {
  1039. collection_init(&listeners);
  1040. mutex_init(&listener_mutex);
  1041. }
  1042. int usbmuxd_events_subscribe(usbmuxd_subscription_context_t *context, usbmuxd_event_cb_t callback, void *user_data)
  1043. {
  1044. if (!context || !callback) {
  1045. return -EINVAL;
  1046. }
  1047. thread_once(&listener_init_once, init_listeners);
  1048. mutex_lock(&listener_mutex);
  1049. *context = malloc(sizeof(struct usbmuxd_subscription_context));
  1050. if (!*context) {
  1051. mutex_unlock(&listener_mutex);
  1052. LIBUSBMUXD_ERROR("ERROR: %s: malloc failed\n", __func__);
  1053. return -ENOMEM;
  1054. }
  1055. (*context)->callback = callback;
  1056. (*context)->user_data = user_data;
  1057. collection_add(&listeners, *context);
  1058. if (devmon == THREAD_T_NULL || !thread_alive(devmon)) {
  1059. mutex_unlock(&listener_mutex);
  1060. int res = thread_new(&devmon, device_monitor, NULL);
  1061. if (res != 0) {
  1062. free(*context);
  1063. LIBUSBMUXD_DEBUG(1, "%s: ERROR: Could not start device watcher thread!\n", __func__);
  1064. return res;
  1065. }
  1066. } else {
  1067. /* we need to submit DEVICE_ADD events to the new listener */
  1068. FOREACH(usbmuxd_device_info_t *dev, &devices) {
  1069. if (dev) {
  1070. usbmuxd_event_t ev;
  1071. ev.event = UE_DEVICE_ADD;
  1072. memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));
  1073. (*context)->callback(&ev, (*context)->user_data);
  1074. }
  1075. } ENDFOREACH
  1076. mutex_unlock(&listener_mutex);
  1077. }
  1078. return 0;
  1079. }
  1080. int usbmuxd_events_unsubscribe(usbmuxd_subscription_context_t context)
  1081. {
  1082. int ret = 0;
  1083. int num = 0;
  1084. if (!context) {
  1085. return -EINVAL;
  1086. }
  1087. mutex_lock(&listener_mutex);
  1088. if (collection_remove(&listeners, context) == 0) {
  1089. FOREACH(usbmuxd_device_info_t *dev, &devices) {
  1090. if (dev) {
  1091. usbmuxd_event_t ev;
  1092. ev.event = UE_DEVICE_REMOVE;
  1093. memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));
  1094. (context)->callback(&ev, (context)->user_data);
  1095. }
  1096. } ENDFOREACH
  1097. free(context);
  1098. }
  1099. num = collection_count(&listeners);
  1100. mutex_unlock(&listener_mutex);
  1101. if (num == 0) {
  1102. int res = 0;
  1103. cancelling = 1;
  1104. socket_shutdown(listenfd, SHUT_RDWR);
  1105. if (thread_alive(devmon)) {
  1106. if (thread_cancel(devmon) < 0) {
  1107. running = 0;
  1108. }
  1109. #if defined(HAVE_INOTIFY) && !defined(HAVE_PTHREAD_CANCEL)
  1110. pthread_kill(devmon, SIGINT);
  1111. #endif
  1112. res = thread_join(devmon);
  1113. thread_free(devmon);
  1114. devmon = THREAD_T_NULL;
  1115. }
  1116. if ((res != 0) && (res != ESRCH)) {
  1117. ret = res;
  1118. }
  1119. }
  1120. return ret;
  1121. }
  1122. int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data)
  1123. {
  1124. if (!callback) {
  1125. return -EINVAL;
  1126. }
  1127. if (event_ctx) {
  1128. usbmuxd_events_unsubscribe(event_ctx);
  1129. event_ctx = NULL;
  1130. }
  1131. return usbmuxd_events_subscribe(&event_ctx, callback, user_data);
  1132. }
  1133. int usbmuxd_unsubscribe(void)
  1134. {
  1135. int res = usbmuxd_events_unsubscribe(event_ctx);
  1136. event_ctx = NULL;
  1137. return res;
  1138. }
  1139. int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)
  1140. {
  1141. int sfd;
  1142. int tag;
  1143. int listen_success = 0;
  1144. uint32_t res;
  1145. struct collection tmpdevs;
  1146. usbmuxd_device_info_t *newlist = NULL;
  1147. struct usbmuxd_header hdr;
  1148. int dev_cnt = 0;
  1149. void *payload = NULL;
  1150. *device_list = NULL;
  1151. retry:
  1152. sfd = connect_usbmuxd_socket();
  1153. if (sfd < 0) {
  1154. LIBUSBMUXD_DEBUG(1, "%s: error opening socket!\n", __func__);
  1155. return sfd;
  1156. }
  1157. tag = ++use_tag;
  1158. if ((proto_version == 1) && (try_list_devices)) {
  1159. if (send_list_devices_packet(sfd, tag) > 0) {
  1160. plist_t list = NULL;
  1161. if ((usbmuxd_get_result(sfd, tag, &res, &list) == 1) && (res == 0)) {
  1162. plist_t devlist = plist_dict_get_item(list, "DeviceList");
  1163. if (devlist && plist_get_node_type(devlist) == PLIST_ARRAY) {
  1164. collection_init(&tmpdevs);
  1165. uint32_t numdevs = plist_array_get_size(devlist);
  1166. uint32_t i;
  1167. for (i = 0; i < numdevs; i++) {
  1168. plist_t pdev = plist_array_get_item(devlist, i);
  1169. plist_t props = plist_dict_get_item(pdev, "Properties");
  1170. usbmuxd_device_info_t *devinfo = device_info_from_plist(props);
  1171. if (!devinfo) {
  1172. socket_close(sfd);
  1173. LIBUSBMUXD_DEBUG(1, "%s: Could not create device info object from properties!\n", __func__);
  1174. plist_free(list);
  1175. return -1;
  1176. }
  1177. collection_add(&tmpdevs, devinfo);
  1178. }
  1179. plist_free(list);
  1180. goto got_device_list;
  1181. }
  1182. } else {
  1183. if (res == RESULT_BADVERSION) {
  1184. proto_version = 0;
  1185. }
  1186. socket_close(sfd);
  1187. try_list_devices = 0;
  1188. plist_free(list);
  1189. goto retry;
  1190. }
  1191. plist_free(list);
  1192. }
  1193. }
  1194. tag = ++use_tag;
  1195. if (send_listen_packet(sfd, tag) > 0) {
  1196. res = -1;
  1197. // get response
  1198. if ((usbmuxd_get_result(sfd, tag, &res, NULL) == 1) && (res == 0)) {
  1199. listen_success = 1;
  1200. } else {
  1201. socket_close(sfd);
  1202. if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
  1203. proto_version = 0;
  1204. goto retry;
  1205. }
  1206. LIBUSBMUXD_DEBUG(1, "%s: Did not get response to scan request (with result=0)...\n", __func__);
  1207. return res;
  1208. }
  1209. }
  1210. if (!listen_success) {
  1211. socket_close(sfd);
  1212. LIBUSBMUXD_DEBUG(1, "%s: Could not send listen request!\n", __func__);
  1213. return -1;
  1214. }
  1215. collection_init(&tmpdevs);
  1216. // receive device list
  1217. while (1) {
  1218. if (receive_packet(sfd, &hdr, &payload, 100) > 0) {
  1219. if (hdr.message == MESSAGE_DEVICE_ADD) {
  1220. usbmuxd_device_info_t *devinfo = payload;
  1221. collection_add(&tmpdevs, devinfo);
  1222. payload = NULL;
  1223. } else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
  1224. uint32_t handle;
  1225. usbmuxd_device_info_t *devinfo = NULL;
  1226. memcpy(&handle, payload, sizeof(uint32_t));
  1227. FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
  1228. if (di && di->handle == handle) {
  1229. devinfo = di;
  1230. break;
  1231. }
  1232. } ENDFOREACH
  1233. if (devinfo) {
  1234. collection_remove(&tmpdevs, devinfo);
  1235. free(devinfo);
  1236. }
  1237. } else {
  1238. LIBUSBMUXD_DEBUG(1, "%s: Unexpected message %d\n", __func__, hdr.message);
  1239. }
  1240. free(payload);
  1241. } else {
  1242. // we _should_ have all of them now.
  1243. // or perhaps an error occurred.
  1244. break;
  1245. }
  1246. }
  1247. got_device_list:
  1248. // explicitly close connection
  1249. socket_close(sfd);
  1250. // create copy of device info entries from collection
  1251. newlist = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t) * (collection_count(&tmpdevs) + 1));
  1252. dev_cnt = 0;
  1253. FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
  1254. if (di) {
  1255. memcpy(&newlist[dev_cnt], di, sizeof(usbmuxd_device_info_t));
  1256. free(di);
  1257. dev_cnt++;
  1258. }
  1259. } ENDFOREACH
  1260. collection_free(&tmpdevs);
  1261. memset(&newlist[dev_cnt], 0, sizeof(usbmuxd_device_info_t));
  1262. *device_list = newlist;
  1263. return dev_cnt;
  1264. }
  1265. int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list)
  1266. {
  1267. if (device_list) {
  1268. free(*device_list);
  1269. }
  1270. return 0;
  1271. }
  1272. int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device)
  1273. {
  1274. usbmuxd_device_info_t *dev_list = NULL;
  1275. usbmuxd_device_info_t *dev = NULL;
  1276. int result = 0;
  1277. int i;
  1278. if (!device) {
  1279. return -EINVAL;
  1280. }
  1281. if (usbmuxd_get_device_list(&dev_list) < 0) {
  1282. return -ENODEV;
  1283. }
  1284. for (i = 0; dev_list[i].handle > 0; i++) {
  1285. if (!udid) {
  1286. if (dev_list[i].conn_type == CONNECTION_TYPE_USB) {
  1287. dev = &dev_list[i];
  1288. break;
  1289. }
  1290. } else if (!strcmp(udid, dev_list[i].udid)) {
  1291. if (dev_list[i].conn_type == CONNECTION_TYPE_USB) {
  1292. dev = &dev_list[i];
  1293. break;
  1294. }
  1295. }
  1296. }
  1297. if (dev) {
  1298. device->handle = dev->handle;
  1299. device->product_id = dev->product_id;
  1300. char *t = stpncpy(device->udid, dev->udid, sizeof(device->udid)-1);
  1301. *t = '\0';
  1302. device->conn_type = dev->conn_type;
  1303. memcpy(device->conn_data, dev->conn_data, sizeof(device->conn_data));
  1304. result = 1;
  1305. }
  1306. usbmuxd_device_list_free(&dev_list);
  1307. return result;
  1308. }
  1309. int usbmuxd_get_device(const char *udid, usbmuxd_device_info_t *device, enum usbmux_lookup_options options)
  1310. {
  1311. usbmuxd_device_info_t *dev_list = NULL;
  1312. usbmuxd_device_info_t *dev_network = NULL;
  1313. usbmuxd_device_info_t *dev_usbmuxd = NULL;
  1314. usbmuxd_device_info_t *dev = NULL;
  1315. int result = 0;
  1316. int i;
  1317. if (!device) {
  1318. return -EINVAL;
  1319. }
  1320. if (usbmuxd_get_device_list(&dev_list) < 0) {
  1321. return -ENODEV;
  1322. }
  1323. if (options == 0) {
  1324. options = DEVICE_LOOKUP_USBMUX;
  1325. }
  1326. for (i = 0; dev_list[i].handle > 0; i++) {
  1327. if (!udid) {
  1328. if ((options & DEVICE_LOOKUP_USBMUX) && (dev_list[i].conn_type == CONNECTION_TYPE_USB)) {
  1329. dev_usbmuxd = &dev_list[i];
  1330. break;
  1331. }
  1332. if ((options & DEVICE_LOOKUP_NETWORK) && (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK)) {
  1333. dev_network = &dev_list[i];
  1334. break;
  1335. }
  1336. } else if (!strcmp(udid, dev_list[i].udid)) {
  1337. if ((options & DEVICE_LOOKUP_USBMUX) && (dev_list[i].conn_type == CONNECTION_TYPE_USB)) {
  1338. dev_usbmuxd = &dev_list[i];
  1339. } else if ((options & DEVICE_LOOKUP_NETWORK) && (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK)) {
  1340. dev_network = &dev_list[i];
  1341. }
  1342. }
  1343. if (dev_usbmuxd && dev_network) {
  1344. break;
  1345. }
  1346. }
  1347. if (dev_network && dev_usbmuxd) {
  1348. dev = (options & DEVICE_LOOKUP_PREFER_NETWORK) ? dev_network : dev_usbmuxd;
  1349. } else if (dev_network) {
  1350. dev = dev_network;
  1351. } else if (dev_usbmuxd) {
  1352. dev = dev_usbmuxd;
  1353. }
  1354. if (dev) {
  1355. device->handle = dev->handle;
  1356. device->product_id = dev->product_id;
  1357. char *t = stpncpy(device->udid, dev->udid, sizeof(device->udid)-1);
  1358. *t = '\0';
  1359. device->conn_type = dev->conn_type;
  1360. memcpy(device->conn_data, dev->conn_data, sizeof(device->conn_data));
  1361. result = 1;
  1362. }
  1363. free(dev_list);
  1364. return result;
  1365. }
  1366. int usbmuxd_connect(const uint32_t handle, const unsigned short port)
  1367. {
  1368. int sfd;
  1369. int tag;
  1370. int connected = 0;
  1371. int result = EBADF;
  1372. retry:
  1373. sfd = connect_usbmuxd_socket();
  1374. if (sfd < 0) {
  1375. LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(-sfd));
  1376. return sfd;
  1377. }
  1378. tag = ++use_tag;
  1379. if (send_connect_packet(sfd, tag, handle, (uint16_t)port) <= 0) {
  1380. LIBUSBMUXD_DEBUG(1, "%s: Error sending connect message!\n", __func__);
  1381. } else {
  1382. // read ACK
  1383. uint32_t res = -1;
  1384. LIBUSBMUXD_DEBUG(2, "%s: Reading connect result...\n", __func__);
  1385. if (usbmuxd_get_result(sfd, tag, &res, NULL) == 1) {
  1386. if (res == 0) {
  1387. LIBUSBMUXD_DEBUG(2, "%s: Connect success!\n", __func__);
  1388. connected = 1;
  1389. } else {
  1390. if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
  1391. proto_version = 0;
  1392. socket_close(sfd);
  1393. goto retry;
  1394. }
  1395. LIBUSBMUXD_DEBUG(1, "%s: Connect failed, Error code=%d\n", __func__, res);
  1396. if (res == RESULT_CONNREFUSED) {
  1397. result = ECONNREFUSED;
  1398. } else if (res == RESULT_BADDEV) {
  1399. result = ENODEV;
  1400. } else {
  1401. result = EBADF;
  1402. }
  1403. }
  1404. }
  1405. }
  1406. if (connected) {
  1407. return sfd;
  1408. }
  1409. socket_close(sfd);
  1410. return -result;
  1411. }
  1412. int usbmuxd_disconnect(int sfd)
  1413. {
  1414. return socket_close(sfd);
  1415. }
  1416. int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes)
  1417. {
  1418. int num_sent;
  1419. if (sfd < 0) {
  1420. return -EINVAL;
  1421. }
  1422. num_sent = socket_send(sfd, (void*)data, len);
  1423. if (num_sent < 0) {
  1424. *sent_bytes = 0;
  1425. LIBUSBMUXD_DEBUG(1, "%s: Error %d when sending: %s\n", __func__, -num_sent, strerror(-num_sent));
  1426. return num_sent;
  1427. }
  1428. if ((uint32_t)num_sent < len) {
  1429. LIBUSBMUXD_DEBUG(1, "%s: Warning: Did not send enough (only %d of %d)\n", __func__, num_sent, len);
  1430. }
  1431. *sent_bytes = num_sent;
  1432. return 0;
  1433. }
  1434. int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
  1435. {
  1436. int num_recv = socket_receive_timeout(sfd, (void*)data, len, 0, timeout);
  1437. if (num_recv < 0) {
  1438. *recv_bytes = 0;
  1439. return num_recv;
  1440. }
  1441. *recv_bytes = num_recv;
  1442. return 0;
  1443. }
  1444. int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes)
  1445. {
  1446. return usbmuxd_recv_timeout(sfd, data, len, recv_bytes, 5000);
  1447. }
  1448. int usbmuxd_read_buid(char **buid)
  1449. {
  1450. int sfd;
  1451. int tag;
  1452. int ret = -1;
  1453. if (!buid) {
  1454. return -EINVAL;
  1455. }
  1456. *buid = NULL;
  1457. sfd = connect_usbmuxd_socket();
  1458. if (sfd < 0) {
  1459. LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(-sfd));
  1460. return sfd;
  1461. }
  1462. proto_version = 1;
  1463. tag = ++use_tag;
  1464. if (send_read_buid_packet(sfd, tag) <= 0) {
  1465. LIBUSBMUXD_DEBUG(1, "%s: Error sending ReadBUID message!\n", __func__);
  1466. } else {
  1467. uint32_t rc = 0;
  1468. plist_t pl = NULL;
  1469. ret = usbmuxd_get_result(sfd, tag, &rc, &pl);
  1470. if ((ret == 1) && (rc == 0)) {
  1471. plist_t node = plist_dict_get_item(pl, "BUID");
  1472. if (node && plist_get_node_type(node) == PLIST_STRING) {
  1473. plist_get_string_val(node, buid);
  1474. }
  1475. ret = 0;
  1476. } else if (ret == 1) {
  1477. ret = -(int)rc;
  1478. }
  1479. plist_free(pl);
  1480. }
  1481. socket_close(sfd);
  1482. return ret;
  1483. }
  1484. int usbmuxd_read_pair_record(const char* record_id, char **record_data, uint32_t *record_size)
  1485. {
  1486. int sfd;
  1487. int tag;
  1488. int ret = -1;
  1489. if (!record_id || !record_data || !record_size) {
  1490. return -EINVAL;
  1491. }
  1492. *record_data = NULL;
  1493. *record_size = 0;
  1494. sfd = connect_usbmuxd_socket();
  1495. if (sfd < 0) {
  1496. LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(-sfd));
  1497. return sfd;
  1498. }
  1499. proto_version = 1;
  1500. tag = ++use_tag;
  1501. if (send_pair_record_packet(sfd, tag, "ReadPairRecord", record_id, 0, NULL) <= 0) {
  1502. LIBUSBMUXD_DEBUG(1, "%s: Error sending ReadPairRecord message!\n", __func__);
  1503. } else {
  1504. uint32_t rc = 0;
  1505. plist_t pl = NULL;
  1506. ret = usbmuxd_get_result(sfd, tag, &rc, &pl);
  1507. if ((ret == 1) && (rc == 0)) {
  1508. plist_t node = plist_dict_get_item(pl, "PairRecordData");
  1509. if (node && plist_get_node_type(node) == PLIST_DATA) {
  1510. uint64_t int64val = 0;
  1511. plist_get_data_val(node, record_data, &int64val);
  1512. if (*record_data && int64val > 0) {
  1513. *record_size = (uint32_t)int64val;
  1514. ret = 0;
  1515. }
  1516. }
  1517. } else if (ret == 1) {
  1518. ret = -(int)rc;
  1519. }
  1520. plist_free(pl);
  1521. }
  1522. socket_close(sfd);
  1523. return ret;
  1524. }
  1525. int usbmuxd_save_pair_record_with_device_id(const char* record_id, uint32_t device_id, const char *record_data, uint32_t record_size)
  1526. {
  1527. int sfd;
  1528. int tag;
  1529. int ret = -1;
  1530. if (!record_id || !record_data || !record_size) {
  1531. return -EINVAL;
  1532. }
  1533. sfd = connect_usbmuxd_socket();
  1534. if (sfd < 0) {
  1535. LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(-sfd));
  1536. return sfd;
  1537. }
  1538. proto_version = 1;
  1539. tag = ++use_tag;
  1540. plist_t data = plist_new_data(record_data, record_size);
  1541. if (send_pair_record_packet(sfd, tag, "SavePairRecord", record_id, device_id, data) <= 0) {
  1542. LIBUSBMUXD_DEBUG(1, "%s: Error sending SavePairRecord message!\n", __func__);
  1543. } else {
  1544. uint32_t rc = 0;
  1545. ret = usbmuxd_get_result(sfd, tag, &rc, NULL);
  1546. if ((ret == 1) && (rc == 0)) {
  1547. ret = 0;
  1548. } else if (ret == 1) {
  1549. ret = -(int)rc;
  1550. LIBUSBMUXD_DEBUG(1, "%s: Error: saving pair record failed: %d\n", __func__, ret);
  1551. }
  1552. }
  1553. plist_free(data);
  1554. socket_close(sfd);
  1555. return ret;
  1556. }
  1557. int usbmuxd_save_pair_record(const char* record_id, const char *record_data, uint32_t record_size)
  1558. {
  1559. return usbmuxd_save_pair_record_with_device_id(record_id, 0, record_data, record_size);
  1560. }
  1561. int usbmuxd_delete_pair_record(const char* record_id)
  1562. {
  1563. int sfd;
  1564. int tag;
  1565. int ret = -1;
  1566. if (!record_id) {
  1567. return -EINVAL;
  1568. }
  1569. sfd = connect_usbmuxd_socket();
  1570. if (sfd < 0) {
  1571. LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(-sfd));
  1572. return sfd;
  1573. }
  1574. proto_version = 1;
  1575. tag = ++use_tag;
  1576. if (send_pair_record_packet(sfd, tag, "DeletePairRecord", record_id, 0, NULL) <= 0) {
  1577. LIBUSBMUXD_DEBUG(1, "%s: Error sending DeletePairRecord message!\n", __func__);
  1578. } else {
  1579. uint32_t rc = 0;
  1580. ret = usbmuxd_get_result(sfd, tag, &rc, NULL);
  1581. if ((ret == 1) && (rc == 0)) {
  1582. ret = 0;
  1583. } else if (ret == 1) {
  1584. ret = -(int)rc;
  1585. LIBUSBMUXD_DEBUG(1, "%s: Error: deleting pair record failed: %d\n", __func__, ret);
  1586. }
  1587. }
  1588. socket_close(sfd);
  1589. return ret;
  1590. }
  1591. void libusbmuxd_set_use_inotify(int set)
  1592. {
  1593. #ifdef HAVE_INOTIFY
  1594. use_inotify = set;
  1595. #endif
  1596. }
  1597. void libusbmuxd_set_debug_level(int level)
  1598. {
  1599. libusbmuxd_debug = level;
  1600. socket_set_verbose(level);
  1601. }
  1602. const char* libusbmuxd_version()
  1603. {
  1604. #ifndef PACKAGE_VERSION
  1605. #error PACKAGE_VERSION is not defined
  1606. #endif
  1607. return PACKAGE_VERSION;
  1608. }