mobilesync.pxi 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. cdef extern from "libimobiledevice/mobilesync.h":
  2. cdef struct mobilesync_client_private:
  3. pass
  4. ctypedef mobilesync_client_private *mobilesync_client_t
  5. ctypedef enum mobilesync_error_t:
  6. MOBILESYNC_E_SUCCESS = 0
  7. MOBILESYNC_E_INVALID_ARG = -1
  8. MOBILESYNC_E_PLIST_ERROR = -2
  9. MOBILESYNC_E_MUX_ERROR = -3
  10. MOBILESYNC_E_BAD_VERSION = -4
  11. MOBILESYNC_E_SYNC_REFUSED = -5
  12. MOBILESYNC_E_CANCELLED = -6
  13. MOBILESYNC_E_WRONG_DIRECTION = -7
  14. MOBILESYNC_E_NOT_READY = -8
  15. MOBILESYNC_E_UNKNOWN_ERROR = -256
  16. ctypedef enum mobilesync_sync_type_t:
  17. MOBILESYNC_SYNC_TYPE_FAST
  18. MOBILESYNC_SYNC_TYPE_SLOW
  19. MOBILESYNC_SYNC_TYPE_RESET
  20. ctypedef struct mobilesync_anchors:
  21. char *device_anchor
  22. char *host_anchor
  23. ctypedef mobilesync_anchors *mobilesync_anchors_t
  24. mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client)
  25. mobilesync_error_t mobilesync_client_free(mobilesync_client_t client)
  26. mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist.plist_t *plist)
  27. mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist.plist_t plist)
  28. mobilesync_error_t mobilesync_start(mobilesync_client_t client, char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description)
  29. mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, char* reason)
  30. mobilesync_error_t mobilesync_finish(mobilesync_client_t client)
  31. mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client)
  32. mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client)
  33. mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist.plist_t *entities, uint8_t *is_last_record, plist.plist_t *actions)
  34. mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client)
  35. mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client)
  36. mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist.plist_t changes, uint8_t is_last_record, plist.plist_t actions)
  37. mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist.plist_t *mapping)
  38. mobilesync_anchors_t mobilesync_anchors_new(char *device_anchor, char *computer_anchor)
  39. void mobilesync_anchors_free(mobilesync_anchors_t anchors)
  40. plist.plist_t mobilesync_actions_new()
  41. void mobilesync_actions_add(plist.plist_t actions, ...)
  42. void mobilesync_actions_free(plist.plist_t actions)
  43. SYNC_TYPE_FAST = MOBILESYNC_SYNC_TYPE_FAST
  44. SYNC_TYPE_SLOW = MOBILESYNC_SYNC_TYPE_SLOW
  45. SYNC_TYPE_RESET = MOBILESYNC_SYNC_TYPE_RESET
  46. cdef class MobileSyncError(BaseError):
  47. def __init__(self, *args, **kwargs):
  48. self._lookup_table = {
  49. MOBILESYNC_E_SUCCESS: "Success",
  50. MOBILESYNC_E_INVALID_ARG: "Invalid argument",
  51. MOBILESYNC_E_PLIST_ERROR: "Property list error",
  52. MOBILESYNC_E_MUX_ERROR: "MUX error",
  53. MOBILESYNC_E_BAD_VERSION: "Bad version",
  54. MOBILESYNC_E_SYNC_REFUSED: "Sync refused",
  55. MOBILESYNC_E_CANCELLED: "Sync cancelled",
  56. MOBILESYNC_E_WRONG_DIRECTION: "Wrong sync direction",
  57. MOBILESYNC_E_NOT_READY: "Not ready to receive changes",
  58. MOBILESYNC_E_UNKNOWN_ERROR: "Unknown error"
  59. }
  60. BaseError.__init__(self, *args, **kwargs)
  61. cdef class MobileSyncClient(DeviceLinkService):
  62. __service_name__ = "com.apple.mobilesync"
  63. cdef mobilesync_client_t _c_client
  64. def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
  65. self.handle_error(mobilesync_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
  66. def __dealloc__(self):
  67. cdef mobilesync_error_t err
  68. if self._c_client is not NULL:
  69. err = mobilesync_client_free(self._c_client)
  70. self.handle_error(err)
  71. cpdef tuple start(self, bytes data_class, bytes device_anchor, bytes host_anchor):
  72. cdef:
  73. mobilesync_anchors_t anchors = NULL
  74. mobilesync_sync_type_t sync_type
  75. uint64_t computer_data_class_version = 1
  76. uint64_t device_data_class_version
  77. char* error_description = NULL
  78. if device_anchor is None:
  79. anchors = mobilesync_anchors_new(NULL, host_anchor)
  80. else:
  81. anchors = mobilesync_anchors_new(device_anchor, host_anchor)
  82. try:
  83. self.handle_error(mobilesync_start(self._c_client, data_class, anchors, computer_data_class_version, &sync_type, &device_data_class_version, &error_description))
  84. return (sync_type, <bint>computer_data_class_version, <bint>device_data_class_version, <bytes>error_description)
  85. except Exception, e:
  86. raise
  87. finally:
  88. mobilesync_anchors_free(anchors)
  89. cpdef finish(self):
  90. self.handle_error(mobilesync_finish(self._c_client))
  91. cpdef cancel(self, bytes reason):
  92. self.handle_error(mobilesync_cancel(self._c_client, reason))
  93. cpdef get_all_records_from_device(self):
  94. self.handle_error(mobilesync_get_all_records_from_device(self._c_client))
  95. cpdef get_changes_from_device(self):
  96. self.handle_error(mobilesync_get_changes_from_device(self._c_client))
  97. cpdef tuple receive_changes(self):
  98. cdef:
  99. plist.plist_t entities = NULL
  100. uint8_t is_last_record = 0
  101. plist.plist_t actions = NULL
  102. try:
  103. self.handle_error(mobilesync_receive_changes(self._c_client, &entities, &is_last_record, &actions))
  104. return (plist.plist_t_to_node(entities), <bint>is_last_record, plist.plist_t_to_node(actions))
  105. except Exception, e:
  106. if entities != NULL:
  107. plist.plist_free(entities)
  108. if actions != NULL:
  109. plist.plist_free(actions)
  110. raise
  111. cpdef acknowledge_changes_from_device(self):
  112. self.handle_error(mobilesync_acknowledge_changes_from_device(self._c_client))
  113. cpdef ready_to_send_changes_from_computer(self):
  114. self.handle_error(mobilesync_ready_to_send_changes_from_computer(self._c_client))
  115. cpdef send_changes(self, plist.Node changes, bint is_last_record, plist.Node actions):
  116. self.handle_error(mobilesync_send_changes(self._c_client, changes._c_node, is_last_record, actions._c_node))
  117. cpdef remap_identifiers(self):
  118. cdef plist.plist_t remapping = NULL
  119. try:
  120. self.handle_error(mobilesync_remap_identifiers(self._c_client, &remapping))
  121. return plist.plist_t_to_node(remapping)
  122. except Exception, e:
  123. if remapping != NULL:
  124. plist.plist_free(remapping)
  125. raise
  126. cdef int16_t _send(self, plist.plist_t node):
  127. return mobilesync_send(self._c_client, node)
  128. cdef int16_t _receive(self, plist.plist_t* node):
  129. return mobilesync_receive(self._c_client, node)
  130. cdef inline BaseError _error(self, int16_t ret):
  131. return MobileSyncError(ret)