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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.iotivity.org/pipermail/iotivity-dev/attachments/20170202/bd4d3d7b/attachment.html>
