Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

P100 support #42

Open
spasea opened this issue Nov 13, 2020 · 16 comments
Open

P100 support #42

spasea opened this issue Nov 13, 2020 · 16 comments

Comments

@spasea
Copy link

spasea commented Nov 13, 2020

Hey, @adumont

I'm wondering: can tp link p100 be controlled through tplink cloud api?
I tried to use HS100 interface, but I've got such response while trying to set relay state to 0 (basically each response was like this)

{
    "error_code": 0,
    "result": {
        "responseData": {
            "error_code": -1003
        }
    }
}

Also this device is visible in my account devices list.
I did some proxy inspection on my phone and found out, that request payload was a bit different from the HS100 one. Mine contained securePassthrough method and encrypted requestData. I think it can be different because it was communicating through local network, but I can be wrong.

Any comment would be appreciated 🙂

@adumont
Copy link
Owner

adumont commented Nov 13, 2020 via email

@spasea
Copy link
Author

spasea commented Nov 13, 2020

@adumont ok, I'll try it

@spasea
Copy link
Author

spasea commented Nov 14, 2020

@adumont I was able to do some debug and found out 2 actions I needed
To get status of the switch - the following request data required

{
    "method": "passthrough",
    "params": {
        "deviceId": "***id***",
        "requestData": {
            "method": "get_device_running_info",
            // without these 2 parameters everything worked as well
            "requestTimeMils": 1605366971489,
	    "terminalUUID": "34-82-B1-3A-23-F2"
        }
    }
}

And response would be like the following

{
    "error_code": 0,
    "result": {
        "responseData": {
            "result": {
                "rssi": -44,
                "time_usage_today": 432,
                "latitude": number,
                "ip": "device_ip",
                "device_on": true,
                "avatar": "table_lamp",
                "time_usage_past30": 725,
                "has_set_location_info": false,
                "time_usage_past7": 725,
                "signal_level": 3,
                "on_time": 399,
                "overheated": false,
                "nickname": "QmVkIGxhbXA=",
                "location": "bedroom",
                "fw_ver": "1.2.1 Build 20200616 Rel. 31218",
                "longitude": number
            },
            "error_code": 0
        }
    }
}

To set the switch status you have to pass these parameters

{
    "method": "passthrough",
    "params": {
        "deviceId": "***id***",
        "requestData": {
            "method": "set_device_info",
            "params": {
                "device_on": true || false
            },
            // without these 2 parameters everything worked as well
            "requestTimeMils": 1605366971489,
	    "terminalUUID": "34-82-B1-3A-23-F2"
        }
    }
}

And response would be as the following

{
    "error_code": 0,
    "result": {
        "responseData": {
            "error_code": 0
        }
    }
}

Currently I don't have much time to do a pull request, but in some future I'll try to do a contribution

@cjdshaw
Copy link

cjdshaw commented Nov 27, 2020

I have a couple of P100s, but they show up in my deviceList with base64 encoded aliases, and status as offline

{
  "error_code": 0,
  "result": {
    "deviceType": "SMART.TAPOPLUG",
    "role": 0,
    "fwVer": "1.3.3",
    "appServerUrl": "https://eu-wap.tplinkcloud.com",
    "deviceRegion": "eu-west-1",
    "deviceId": "####",
    "deviceName": "P100",
    "deviceHwVer": "1.0",
    "alias": "RnJvbnQgZG9vciBsaWdodHM=",
    "oemId": "####",
    "deviceMac": "####",
    "deviceModel": "P100",
    "hwId": "####",
    "fwId": "####",
    "isSameRegion": true,
    "status": 0
  }
}

If I try to do anything with them, I just get

{
  "error_code": -20571,
  "msg": "Device is offline"
}

I wonder why yours are different

@spasea
Copy link
Author

spasea commented Jan 8, 2021

@cjdshaw I have another p100 socket with hardware version 1.0. Here you have another api endpoint with different request/response structure. Basically you should hit another endpoint url. You can trace your app requests through some kind of proxy

@tnmendes
Copy link

tnmendes commented Jan 9, 2021

@spasea I can see that the responses that you have are from the old firmware when you updated your Tapo firmware you will other response types.

@cjdshaw To get the tapo server you need to run one request to:
GET: https://app-server.iot.i.tplinknbu.com/v1/server-info

@cjdshaw
Copy link

cjdshaw commented Jan 9, 2021

Thanks guys, but I feel like I'm being stupid here

@tnmendes: I've got the endpoints from that URL
{ "appServerUrl": "https://euw1-app-server.iot.i.tplinknbu.com", "cloudGatewayUrl": "euw1-app-cloudgateway.iot.i.tplinknbu.com", "securityServerUrl": "https://euw1-security.iot.i.tplinknbu.com" }

but any POST I send to any of them comes back 404 or empty. Are you using the token from the Kasa login, or do I need to do a separate auth for Tapo?

I've tried going through a proxy, but the app just stops working. I'm guessing that it uses certificate pinning so doesn't like the substituted certificate. I can see the hosts it's trying to reach, but not the full path or the request data

Any tips you can give me to go further would be much appreciated

If it's useful to anyone, I've attached my Python script that I use to control / query my Kasa devices. I'd like to update it to support Tapo too

kasa_control.py.zip

@adumont
Copy link
Owner

adumont commented Jan 9, 2021 via email

@cjdshaw
Copy link

cjdshaw commented Jan 10, 2021

@adumont Thanks. Time for me to jailbreak one of my iOS devices, I guess!

@spasea
Copy link
Author

spasea commented Jan 10, 2021

@cjdshaw if you need to just trace api requests - you can use some kind of solution like charles. As for me - it's easier than to do a jailbreak 🙂
You can install certificate on the device and trace ssl connection as well (I did it with my android, but it's also possible to install cert on ios device). Also you can map remote ips to your local ones (in case you need it)

@cjdshaw
Copy link

cjdshaw commented Jan 10, 2021

@spasea Charles works for local calls, but the Tapo and Kasa apps both seem to use certificate pinning for cloud calls. That means they check the certificate they get against one stored in the app package. Since the Charles certificate doesn't match, they refuse to communicate. As @adumont mentioned, you have to use Frida/Objection to bypass this, which needs a jailbreak.

If you've got a simpler way to do this without jailbreaking, I'd love to hear about it

@spasea
Copy link
Author

spasea commented Jan 10, 2021

@cjdshaw I think I didn't quite get your point. If you want - you can explain your case in more details. Mine was about request tracing and then using them in your own app, f.ex. do a trace to change socket state and then use the same api endpoint to change the state by your own. To do such a tracing - you need just to install Charles cert on your device (at least this worked for me with android Tapo app).

@cjdshaw
Copy link

cjdshaw commented Jan 10, 2021

@spasea That’s exactly what I’m trying to do, using cloud endpoints, not local network communication though. I’ve installed the Charles certificate and I can inspect https browser traffic, so everything is working as it should, but the Kasa and Tapo apps don’t work while SSL proxying is enabled. Interesting that they work OK on Android. Are you using an older OS or app version? I’ll see if I can borrow an Android device and try it out

@adumont
Copy link
Owner

adumont commented Jan 10, 2021 via email

@cjdshaw
Copy link

cjdshaw commented Jan 11, 2021

Thanks guys. I remembered I had an old Kindle Fire, so I set that up with the Charles proxy and certificate. The Tapo app works fine through the proxy but Kasa still doesn't strangely. I've made a lot of progress with API calls. Updated script attached, if anyone's interested
kasa_control_wip.py.zip

@jkscx
Copy link

jkscx commented Mar 30, 2023

Sorry for resurrecting such an old thread, but did anyone maybe figure out the request structure (for the P100 or similar)?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants