Skip to content

Commit

Permalink
HomeKit ADK implementation
Browse files Browse the repository at this point in the history
Based on bb76ec
  • Loading branch information
aajain-com committed Dec 18, 2019
0 parents commit aa2b08c
Show file tree
Hide file tree
Showing 321 changed files with 86,385 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
BasedOnStyle: WebKit

# Indentation
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
TabWidth: 4
UseTab: Never

AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveMacros: true
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBraces: Attach
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BinPackParameters: false
BinPackArguments: false
ColumnLimit: 120
IndentWrappedFunctionNames: true
MaxEmptyLinesToKeep: 1
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PointerAlignment: Left
SortIncludes: false
SpaceAfterCStyleCast: true
SpacesBeforeTrailingComments: 1
SpacesInContainerLiterals: false
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Build generated
Output/

# Exclude .DS_Store
.DS_Store

# VIM temporary files
*.swp
*.swo
*.tags*

# Pycharm temporary files
.idea/

.HomeKitStore

# Open source export
export/
247 changes: 247 additions & 0 deletions Applications/Lightbulb/App.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
// Copyright (c) 2015-2019 The HomeKit ADK Contributors
//
// Licensed under the Apache License, Version 2.0 (the “License”);
// you may not use this file except in compliance with the License.
// See [CONTRIBUTORS.md] for the list of HomeKit ADK project authors.

// An example that implements the light bulb HomeKit profile. It can serve as a basic implementation for
// any platform. The accessory logic implementation is reduced to internal state updates and log output.
//
// This implementation is platform-independent.
//
// The code consists of multiple parts:
//
// 1. The definition of the accessory configuration and its internal state.
//
// 2. Helper functions to load and save the state of the accessory.
//
// 3. The definitions for the HomeKit attribute database.
//
// 4. The callbacks that implement the actual behavior of the accessory, in this
// case here they merely access the global accessory state variable and write
// to the log to make the behavior easily observable.
//
// 5. The initialization of the accessory state.
//
// 6. Callbacks that notify the server in case their associated value has changed.

#include "HAP.h"

#include "App.h"
#include "DB.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Domain used in the key value store for application data.
*
* Purged: On factory reset.
*/
#define kAppKeyValueStoreDomain_Configuration ((HAPPlatformKeyValueStoreDomain) 0x00)

/**
* Key used in the key value store to store the configuration state.
*
* Purged: On factory reset.
*/
#define kAppKeyValueStoreKey_Configuration_State ((HAPPlatformKeyValueStoreDomain) 0x00)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Global accessory configuration.
*/
typedef struct {
struct {
bool lightBulbOn;
} state;
HAPAccessoryServerRef* server;
HAPPlatformKeyValueStoreRef keyValueStore;
} AccessoryConfiguration;

static AccessoryConfiguration accessoryConfiguration;

//----------------------------------------------------------------------------------------------------------------------

/**
* Load the accessory state from persistent memory.
*/
static void LoadAccessoryState(void) {
HAPPrecondition(accessoryConfiguration.keyValueStore);

HAPError err;

// Load persistent state if available
bool found;
size_t numBytes;

err = HAPPlatformKeyValueStoreGet(
accessoryConfiguration.keyValueStore,
kAppKeyValueStoreDomain_Configuration,
kAppKeyValueStoreKey_Configuration_State,
&accessoryConfiguration.state,
sizeof accessoryConfiguration.state,
&numBytes,
&found);

if (err) {
HAPAssert(err == kHAPError_Unknown);
HAPFatalError();
}
if (!found || numBytes != sizeof accessoryConfiguration.state) {
if (found) {
HAPLogError(&kHAPLog_Default, "Unexpected app state found in key-value store. Resetting to default.");
}
HAPRawBufferZero(&accessoryConfiguration.state, sizeof accessoryConfiguration.state);
}
}

/**
* Save the accessory state to persistent memory.
*/
static void SaveAccessoryState(void) {
HAPPrecondition(accessoryConfiguration.keyValueStore);

HAPError err;
err = HAPPlatformKeyValueStoreSet(
accessoryConfiguration.keyValueStore,
kAppKeyValueStoreDomain_Configuration,
kAppKeyValueStoreKey_Configuration_State,
&accessoryConfiguration.state,
sizeof accessoryConfiguration.state);
if (err) {
HAPAssert(err == kHAPError_Unknown);
HAPFatalError();
}
}

//----------------------------------------------------------------------------------------------------------------------

/**
* HomeKit accessory that provides the Light Bulb service.
*
* Note: Not constant to enable BCT Manual Name Change.
*/
static HAPAccessory accessory = { .aid = 1,
.category = kHAPAccessoryCategory_Lighting,
.name = "Acme Light Bulb",
.manufacturer = "Acme",
.model = "LightBulb1,1",
.serialNumber = "099DB48E9E28",
.firmwareVersion = "1",
.hardwareVersion = "1",
.services = (const HAPService* const[]) { &accessoryInformationService,
&hapProtocolInformationService,
&pairingService,
&lightBulbService,
NULL },
.callbacks = { .identify = IdentifyAccessory } };

//----------------------------------------------------------------------------------------------------------------------

HAP_RESULT_USE_CHECK
HAPError IdentifyAccessory(
HAPAccessoryServerRef* server HAP_UNUSED,
const HAPAccessoryIdentifyRequest* request HAP_UNUSED,
void* _Nullable context HAP_UNUSED) {
HAPLogInfo(&kHAPLog_Default, "%s", __func__);
return kHAPError_None;
}

HAP_RESULT_USE_CHECK
HAPError HandleLightBulbOnRead(
HAPAccessoryServerRef* server HAP_UNUSED,
const HAPBoolCharacteristicReadRequest* request HAP_UNUSED,
bool* value,
void* _Nullable context HAP_UNUSED) {
*value = accessoryConfiguration.state.lightBulbOn;
HAPLogInfo(&kHAPLog_Default, "%s: %s", __func__, *value ? "true" : "false");

return kHAPError_None;
}

HAP_RESULT_USE_CHECK
HAPError HandleLightBulbOnWrite(
HAPAccessoryServerRef* server,
const HAPBoolCharacteristicWriteRequest* request,
bool value,
void* _Nullable context HAP_UNUSED) {
HAPLogInfo(&kHAPLog_Default, "%s: %s", __func__, value ? "true" : "false");
if (accessoryConfiguration.state.lightBulbOn != value) {
accessoryConfiguration.state.lightBulbOn = value;

SaveAccessoryState();

HAPAccessoryServerRaiseEvent(server, request->characteristic, request->service, request->accessory);
}

return kHAPError_None;
}

//----------------------------------------------------------------------------------------------------------------------

void AccessoryNotification(
const HAPAccessory* accessory,
const HAPService* service,
const HAPCharacteristic* characteristic,
void* ctx) {
HAPLogInfo(&kHAPLog_Default, "Accessory Notification");

HAPAccessoryServerRaiseEvent(accessoryConfiguration.server, characteristic, service, accessory);
}

void AppCreate(HAPAccessoryServerRef* server, HAPPlatformKeyValueStoreRef keyValueStore) {
HAPPrecondition(server);
HAPPrecondition(keyValueStore);

HAPLogInfo(&kHAPLog_Default, "%s", __func__);

HAPRawBufferZero(&accessoryConfiguration, sizeof accessoryConfiguration);
accessoryConfiguration.server = server;
accessoryConfiguration.keyValueStore = keyValueStore;
LoadAccessoryState();
}

void AppRelease(void) {
}

void AppAccessoryServerStart(void) {
HAPAccessoryServerStart(accessoryConfiguration.server, &accessory);
}

//----------------------------------------------------------------------------------------------------------------------

void AccessoryServerHandleUpdatedState(HAPAccessoryServerRef* server, void* _Nullable context) {
HAPPrecondition(server);
HAPPrecondition(!context);

switch (HAPAccessoryServerGetState(server)) {
case kHAPAccessoryServerState_Idle: {
HAPLogInfo(&kHAPLog_Default, "Accessory Server State did update: Idle.");
return;
}
case kHAPAccessoryServerState_Running: {
HAPLogInfo(&kHAPLog_Default, "Accessory Server State did update: Running.");
return;
}
case kHAPAccessoryServerState_Stopping: {
HAPLogInfo(&kHAPLog_Default, "Accessory Server State did update: Stopping.");
return;
}
}
HAPFatalError();
}

const HAPAccessory* AppGetAccessoryInfo() {
return &accessory;
}

void AppInitialize(
HAPAccessoryServerOptions* hapAccessoryServerOptions,
HAPPlatform* hapPlatform,
HAPAccessoryServerCallbacks* hapAccessoryServerCallbacks) {
/*no-op*/
}

void AppDeinitialize() {
/*no-op*/
}
Loading

0 comments on commit aa2b08c

Please sign in to comment.