George Nash is now working on this with me, and this is getting closer to being completed, currently in the multiple-device-support<https://gerrit.iotivity.org/gerrit/#/q/status:open+project:iotivity+branch:multiple-device-support> branch. An addendum to the original design note, which I sent to George, is as follows. Putting it here on the list for visibility per the development workflow<https://wiki.iotivity.org/development_workflow> process.
There are two types of apps/unit tests: things that call OCInit() and things that don’t. Examples of unit tests that call OCInit include: service\easy-setup\enrollee\unittests\ESEnrolleeTest.cpp service\coap-http-proxy\unittests\CoAPHttpUnitTest.cpp TEST(StackDevice, CreateExtraDevice) in stacktests.cpp etc OCInit calls OCInit1 which calls OCInit2 which calls OCInitializeInternal, and that’s what sets the default local device. Unit tests that don’t call OCInit() need to handle the local device themselves. Examples include: TEST(StackZoneId, getZoneId) in stacktests.cpp creates a local device itself TEST(PstatResourceTest, InitPstatResource) in pstatresource.cpp create a local device itself TEST(CASetPortNumberTest, CASetPortNumberToAssign) in ca_api_unittest.cpp just creates a dummy one on the stack In my view, the general rule should be that if the unit test is testing something that would be done inside of OCInit() like InitPstatResource, then it should handle the local device itself since it doesn’t want to just call OCInit(). For unit tests that test functionality that is only relevant after OCInit(), and that functionality needs a local device, then the unit test should call OCInit(). Dave From: Dave Thaler Sent: Thursday, February 2, 2017 9:56 AM To: 최우제 (Uze Choi) <[email protected]>; [email protected] Subject: RE: [dev] Proposed Design Approach for [IOT-1379] Multi-Device Support From: [email protected]<mailto:[email protected]> [mailto:[email protected]] On Behalf Of ??? (Uze Choi) Sent: Thursday, February 2, 2017 4:21 AM To: [email protected]<mailto:[email protected]> Subject: Re: [dev] Proposed Design Approach for [IOT-1379] Multi-Device Support Hi Dave, Diagram will help us understood more easily. Posting into IoTivity wiki is good starting. [DT] https://wiki.iotivity.org/development_workflow says discussion should be on the list, and says nothing about a wiki page. If you think we should have wiki pages as part of the recommended process, then that page should be updated. (I have no objection.) Anyway, Let me correct my understand has difference from yours. For each additional logical device, additional CA stack will be initiated with OCLocalDeviceHandle. OCLocalDeviceHandle may be associated with resource handles for its logical device. From Security perspective, multiple ownership transfer should be executed, which is cumbersome step. [DT] All correct. Do you think IoTivity should have multiple sockets for TCP case? [DT] Yes. Same answer as if there were multiple processes. The “eps” values are different for each device. It looks inefficient, multiplexer can be clue to resolve this issue which is same practice in IoTivity BLE GATT implementation. Regarding OCDevAddr, Let think about adding the other info also such as zone id. BR, Uze Choi From: [email protected]<mailto:[email protected]> [mailto:[email protected]] On Behalf Of Dave Thaler via iotivity-dev Sent: Thursday, February 02, 2017 10:26 AM To: [email protected]<mailto:[email protected]> Subject: [dev] Proposed Design Approach for [IOT-1379] Multi-Device Support Here's a summary of how I propose this be solved. Let me know if you see issues, or have additions since there may be some things I'm forgetting below. The primary problem is that local device state is currently global, and it instead needs to be dynamically allocatable so that there can be multiple instances. A secondary problem is the duplication of types between the stack layer and the connectivity abstraction layer. Indeed, cacommon.h already contains the implied todo statement "The CA layer should used the OC types when build allows that." The duplication of types prevents type-safety (because nothing guarantees they match at compile time, you just hope the tests would fail if someone does something wrong), and causes code to be less readable due to type casts. Finally, it causes developer headaches trying to get the includes and include paths right. Here's a list of some of the key things that need to be moved from global to per-local-device-state: * Port # configuration * Set of sockets * Handles to well-known resources (platform, device, introspection, doxm, pstat, pconf, etc.) * Security state per well-known security resource (OicSec_Acl_t, Oic_Sec_Amacl_t, OicSecDoxm_t, etc.) * Presence state, if WITH_PRESENCE is defined * ServerResponseTree Proposed design details: * In the public octypes.h file used by apps, define an opaque OCLocalDeviceHandle for use with new "public" APIs (i.e., ones published into the out/ directory and meant to be callable from apps). * There will automatically be 1 default local device, such that all existing public APIs continue to work unmodified. Only apps that want to use multiple devices will need to use additional APIs. Thus, existing app compat is preserved. * Add new public APIs (or overloads or optional args in some of the C++ cases) that accept a local device handle, and new APIs to add/delete a new local device other than the default one. * Put previously global but device-specific CA-layer state (like sockets) into a new structure called, say, CALocalDeviceState_t. * Put previously global but device-specific stack-layer state (like security) into a new structure called, say, OCLocalDeviceState. * Create a new common internal CALocalDevice_t structure in cacommon.h (where CAGlobals_t already is, so it can be used from both layers) which contains a pointer to struct CALocalDeviceState, and a pointer to struct OCLocalDeviceState. OCLocalDeviceHandle would then be a public opaque pointer to CALocalDevice_t. * Rename resource\csdk\stack\include\internal\ocresource.h to ocresourceinternal.h to prevent confusion (e.g., in source debugging) with resource\include\OCResource.h on case-insensitive filesystems. This follows the naming precedent of ocstack.h vs ocstackinternal.h. Note that we cannot rename OCResource.h to OCResource.hpp because it's a public file and that would break apps. * To reduce the number of internal APIs that would have to pass around another pointer, add a field with the CALocalDevice_t pointer into a couple existing private structs that are commonly passed around (potential examples: SslEndpoint_t, OCProvisionDev_t, OCServerRequest, DiscoveryInfo). Question: Do we think it's ok to extend OCDevAddr with a field at the end? If OCDevAddr is never allocated by an app and passed into the stack, it would be safe. If it could be allocated by an app and passed into the stack, it is not safe to extend since it would break backwards compatibility. If it can be extended, it's less changes to various APIs, but it seems more risky to me. Dave
_______________________________________________ iotivity-dev mailing list [email protected] https://lists.iotivity.org/mailman/listinfo/iotivity-dev
