maximkulkin / esp-homekit

Apple HomeKit accessory server library for ESP-OPEN-RTOS
MIT License
1.1k stars 168 forks source link

Feature Request: Make Client Requests from One Device to Another Device #152

Open mriksman opened 4 years ago

mriksman commented 4 years ago

Hey,

RavenSystem's esp-homekit-devices allows unencrypted client commands by simply modifying these lines https://github.com/RavenSystem/esp-homekit-devices/blob/master/external_libs/homekit/src/server.c#L2984.

You can then send standard unencrypted HTTP URL like

curl -X PUT -d '{"characteristics":[{"aid":1,"iid":9,"value":true}]}' http://device_ip_address:5556/characteristic

Is it possible to have a function in esp-homekit to send an encrypted command to another esp-homekit device?

Use-case; 2-way light switch. Configure one light switch's callback function to send a HTTP PUT request to another esp-homekit device.

beckmx commented 4 years ago

You would need to modify the server, as in raven, there is a function around there that I remember gives you the unencrypted result of the message, however keep in mind that what you want might be a bridge, a device that links several devices inside. You can also use the mdns service to track devices with the same descriptio. I personally implemented this by opening another connection, (unencrypted) to avoid modifying the core more than what I needed to.

mriksman commented 4 years ago

I modified the following lines https://github.com/maximkulkin/esp-homekit/blob/9824dc5eb7b31a74121316d6b1a344133fdb447d/src/server.c#L2936-L2984

//    if (!context->encrypted) {
        switch(context->endpoint) {
            case HOMEKIT_ENDPOINT_PAIR_SETUP: {
                homekit_server_on_pair_setup(context, (const byte *)context->body, context->body_length);
                break;
            }
            case HOMEKIT_ENDPOINT_PAIR_VERIFY: {
                homekit_server_on_pair_verify(context, (const byte *)context->body, context->body_length);
                break;
            }
//            default: {
//                DEBUG("Unknown endpoint");
//                send_404_response(context);
//                break;
//            }
//        }
//    } else {
//        switch(context->endpoint) {
            case HOMEKIT_ENDPOINT_IDENTIFY: {
                if (context->encrypted || true) {
                    homekit_server_on_identify(context);
                }
                break;
            }
            case HOMEKIT_ENDPOINT_GET_ACCESSORIES: {
                if (context->encrypted || true) {
                    homekit_server_on_get_accessories(context);
                }
                break;
            }
            case HOMEKIT_ENDPOINT_GET_CHARACTERISTICS: {
                if (context->encrypted || true) {
                    homekit_server_on_get_characteristics(context);
                }
                break;
            }
            case HOMEKIT_ENDPOINT_UPDATE_CHARACTERISTICS: {
                if (context->encrypted || true) {
                    homekit_server_on_update_characteristics(context, (const byte *)context->body, context->body_length);
                }
                break;
            }
            case HOMEKIT_ENDPOINT_PAIRINGS: {
                if (context->encrypted || true) {
                    homekit_server_on_pairings(context, (const byte *)context->body, context->body_length);
                }
                break;
            }
            case HOMEKIT_ENDPOINT_RESOURCE: {
                if (context->encrypted || true) {
                    homekit_server_on_resource(context);
                }
                break;
            }
            default: {
                DEBUG("Unknown endpoint");
                send_404_response(context);
                break;
            }
        }
//    }

And unencrypted commands work great.

The 'Feature Request' would be to have the connections encrypted so they conformed to the HomeKit standard. Unfortunately, my skills are limited to commenting code, copy-paste code, and some educated guessing; this feature is so far beyond the realm of my abilities...

I don't think a 'Bridge' is what I need. Right now, esp-homekit is a server only. Really, it would need to implement a client side connection (much like your iPhone) and pair with the remote device to establish the ephemeral shared secret to use for encryption.

This feature request is low priority; unencrypted commands work fine, and I don't need to implement them often; only for 2-way switching, like on a stair case. It'd just be nice to have.

Right now, I plan to save the command as a JSON with host, HTTP method and payload. That way, it can be used with any HTTP API. For sending a payload to another esp-homekit device, the payload is something like; {"characteristics":[{"aid":1,"iid":9,"value":"ON"},{"aid":1,"iid":9,"value":"BRIGHTNESS"}]}