From 0c38c20aac15e6663c6934fb4ff1d39f10b50e5b Mon Sep 17 00:00:00 2001
From: Markus Birth <mbirth@gmail.com>
Date: Sat, 17 Oct 2015 20:05:46 +0200
Subject: [PATCH] Added PTP Command_Request support and Theta-commands for
 sessions and shooting.

---
 main.py  |  2 +-
 ptpip.py | 29 +++++++++++++++++++++++++++++
 theta.py | 16 ++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/main.py b/main.py
index aea621b..d5ae052 100644
--- a/main.py
+++ b/main.py
@@ -29,5 +29,5 @@ def tc():
     if not p:
         print("Connect failed!")
     else:
-        answer = p.initCommand('1234567812345678', 'WiPy')
+        answer = t.initPTP()
         print(answer)
diff --git a/ptpip.py b/ptpip.py
index 8a87834..9f7a6a2 100644
--- a/ptpip.py
+++ b/ptpip.py
@@ -1,6 +1,11 @@
 """
 PTP/IP class for MicroPython
 @author Markus Birth <markus@birth-online.de>
+
+PTP packet structure: http://www.gphoto.org/doc/ptpip.php
+                  and https://github.com/gphoto/libgphoto2/blob/master/camlibs/ptp2/PTPIP.TXT
+PTP example implementation in JavaScript: https://github.com/feklee/ptp.js
+PTP response codes: http://www.javased.com/?source_dir=cameraptp/src/main/java/ste/ptp/Response.java
 """
 import binascii
 import socket
@@ -72,4 +77,28 @@ class PTPIP:
         session_id  = struct.unpack('<I', result[1][0:4])[0]
         remote_guid = binascii.hexlify(result[1][4:20])
         remote_name = self.utf16to8(result[1][20:])
+        self.trans_id = 0
         return (session_id, remote_guid, remote_name)
+
+    def createCommand(self, cmd_code, cmd_args):
+        if type(cmd_args) is not list:
+            print("Specify cmd_args as list!")
+            return False
+        self.trans_id += 1
+        payload = b''
+        payload += struct.pack('<IHI', 1, cmd_code, self.trans_id)
+        for a in cmd_args:
+            payload += struct.pack('<I', a)
+        pkg = self.createPkg(6, payload)
+        self.socket.send(pkg)
+        result = self.recvPkg()
+        if result[0] != 7:
+            print("Answer package was of type: %i (%s)" % (result[0], result[1]))
+            return False
+        (response_code, trans_id) = struct.unpack('<HI', result[1][0:6])
+        remainder = result[1][6:]
+        args = []
+        while len(remainder) > 0:
+            args.append(struct.unpack('<I', remainder[:4]))
+            remainder = remainder[4:]
+        return (response_code, trans_id, args)
diff --git a/theta.py b/theta.py
index 4523a05..9b9a0a9 100644
--- a/theta.py
+++ b/theta.py
@@ -37,5 +37,21 @@ class Theta:
         self.ptpip = ptpip.PTPIP('192.168.1.1')
         return self.ptpip
 
+    def initPTP(self):
+        answer = self.ptpip.initCommand('1234567812345678', 'WiPy')
+        return answer
+
+    def openSession(self):
+        answer = self.ptpip.createCommand(0x1002, [])
+        return answer
+
+    def closeSession(self):
+        answer = self.ptpip.createCommand(0x1003, [])
+        return answer
+
+    def shoot(self):
+        answer = self.ptpip.createCommand(0x100e, [0x0, 0x0])
+        return answer
+
     def getPTPIP(self):
         return self.ptpip