diff --git a/CMakeLists.txt b/CMakeLists.txt index 28bc748908..6fe49afa58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,9 +153,7 @@ if(OC_CLOUD_ENABLED) set(CLOUD_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/api/cloud) endif() -if(UNIX) - file(GLOB PYTHON_SRC python/*.c) -endif() +file(GLOB PYTHON_SRC python/*.c) ######## Define link dependencies ######## set(PRIVATE_LINK_LIBS "") @@ -220,13 +218,13 @@ if(OC_CLOUD_ENABLED) endif() endif() -if(UNIX) - add_library(python-obj OBJECT ${PYTHON_SRC}) - target_compile_definitions(python-obj PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} PUBLIC ${PUBLIC_COMPILE_DEFINITIONS} "OC_CLIENT") - target_include_directories(python-obj PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/port ${PORT_INCLUDE_DIR}) - if(OC_SECURITY_ENABLED) - target_include_directories(python-obj PRIVATE ${MBEDTLS_INCLUDE_DIRS}) - endif() +add_library(python-obj OBJECT ${PYTHON_SRC}) +target_compile_definitions(python-obj PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} OC_LIBRARY_EXPORT PUBLIC ${PUBLIC_COMPILE_DEFINITIONS} "OC_LIBRARY" "OC_CLIENT") +set_property(TARGET python-obj PROPERTY C_VISIBILITY_PRESET hidden) +set_property(TARGET python-obj PROPERTY VISIBILITY_INLINES_HIDDEN ON) +target_include_directories(python-obj PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/port ${PORT_INCLUDE_DIR}) +if(OC_SECURITY_ENABLED) + target_include_directories(python-obj PRIVATE ${MBEDTLS_INCLUDE_DIRS}) endif() ######## Compose static and shared libraries ######## @@ -406,35 +404,33 @@ if(NOT MSVC) endif() # Python client -if(UNIX) - set(client-python-lib-obj - $ - $ - $ - $ - ) - if(OC_SECURITY_ENABLED) - list(APPEND client-python-lib-obj $) - endif() - add_library(client-python-shared SHARED ${client-python-lib-obj}) - target_link_libraries(client-python-shared PRIVATE ${PRIVATE_LINK_LIBS}) - target_compile_definitions(client-python-shared PUBLIC - $ - $ - ) - target_include_directories(client-python-shared PUBLIC - $ - $ - ) - if(OC_SECURITY_ENABLED) - target_include_directories(client-python-shared PUBLIC "$") - endif() - set_target_properties(client-python-shared PROPERTIES - OUTPUT_NAME "iotivity-lite-client-python" - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - ) +set(client-python-lib-obj + $ + $ + $ + $ +) +if(OC_SECURITY_ENABLED) + list(APPEND client-python-lib-obj $) endif() +add_library(client-python-shared SHARED ${client-python-lib-obj}) +target_link_libraries(client-python-shared PRIVATE ${PRIVATE_LINK_LIBS}) +target_compile_definitions(client-python-shared PUBLIC + $ + $ +) +target_include_directories(client-python-shared PUBLIC + $ + $ +) +if(OC_SECURITY_ENABLED) + target_include_directories(client-python-shared PUBLIC "$") +endif() +set_target_properties(client-python-shared PROPERTIES + OUTPUT_NAME "iotivity-lite-client-python" + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) ######## Units tests (UNIX only) ######## include(CTest) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 7c693dfc35..6c65ffdc1f 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -123,19 +123,19 @@ if(UNIX) ) target_link_libraries(cloud_server client-server-static) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/cloud_server_creds) - + add_executable(cloud_client ${PROJECT_SOURCE_DIR}/cloud_client.c ) target_link_libraries(cloud_client client-server-static) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/cloud_client_creds) - + add_executable(cloud_proxy ${PROJECT_SOURCE_DIR}/cloud_proxy.c ) target_link_libraries(cloud_proxy client-server-static) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/cloud_proxy_creds) - + add_executable(cloud_tests ${PROJECT_SOURCE_DIR}/cloud_certification_tests.c ) diff --git a/include/oc_export.h b/include/oc_export.h new file mode 100644 index 0000000000..84efcd912d --- /dev/null +++ b/include/oc_export.h @@ -0,0 +1,42 @@ +/* +// Copyright (c) 2022 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#ifndef OC_EXPORT_H +#define OC_EXPORT_H + +#ifdef _WIN32 +#define OC_EXPORT __declspec(dllexport) +#define OC_IMPORT __declspec(dllimport) +#elif (defined __GNUC__ && __GNUC__ >= 4) +#define OC_EXPORT __attribute__((visibility("default"))) +#define OC_IMPORT +#else /* !__GNUC__ || __GNUC__ < 4 */ +#warning "Shared libraries not supported" +#define OC_EXPORT +#define OC_IMPORT +#endif /* _WIN32 */ + +#ifdef OC_LIBRARY +#ifdef OC_LIBRARY_EXPORT +#define OC_API OC_EXPORT +#else /* !OC_LIBRARY_EXPORT*/ +#define OC_API OC_IMPORT +#endif /* OC_LIBRARY_EXPORT */ +#else /* !OC_LIBRARY */ +#define OC_API +#endif /* OC_LIBRARY */ + +#endif /* OC_EXPORT_H */ diff --git a/include/oc_uuid.h b/include/oc_uuid.h index 7b5837d3b0..5eac6b8663 100644 --- a/include/oc_uuid.h +++ b/include/oc_uuid.h @@ -24,6 +24,7 @@ #ifndef OC_UUID_H #define OC_UUID_H +#include "oc_export.h" #include #ifdef __cplusplus @@ -59,6 +60,7 @@ typedef struct * @param[in] str the UUID string * @param[out] uuid the oc_uuid_t to hold the UUID bits. */ +OC_API void oc_str_to_uuid(const char *str, oc_uuid_t *uuid); /** @@ -84,6 +86,7 @@ void oc_str_to_uuid(const char *str, oc_uuid_t *uuid); * @param [in] buflen The size of the input buffer. * Recommend always using OC_UUID_LEN for buflen. */ +OC_API void oc_uuid_to_str(const oc_uuid_t *uuid, char *buffer, int buflen); /** * Generate a random Universally Unique IDentifier (UUID) @@ -100,6 +103,7 @@ void oc_uuid_to_str(const oc_uuid_t *uuid, char *buffer, int buflen); * * @param[out] uuid the randomly generated UUID */ +OC_API void oc_gen_uuid(oc_uuid_t *uuid); #ifdef __cplusplus diff --git a/port/oc_random.h b/port/oc_random.h index 58851961aa..277aefaa98 100644 --- a/port/oc_random.h +++ b/port/oc_random.h @@ -37,6 +37,8 @@ #ifndef OC_RANDOM_H #define OC_RANDOM_H +#include "oc_export.h" + #ifdef __cplusplus extern "C" { #endif @@ -45,6 +47,7 @@ extern "C" { * @brief Initialize the pseudo-random generator. * */ +OC_API void oc_random_init(void); /** @@ -52,12 +55,14 @@ void oc_random_init(void); * * @return A pseudo-random number. */ +OC_API unsigned int oc_random_value(void); /** * @brief destroy the pseudo-random generator * */ +OC_API void oc_random_destroy(void); #ifdef __cplusplus diff --git a/python/oc_python.c b/python/oc_python.c index dc1528c62e..3b194e24d3 100644 --- a/python/oc_python.c +++ b/python/oc_python.c @@ -22,6 +22,7 @@ #include "oc_api.h" #include "oc_core_res.h" #include "oc_obt.h" +#include "oc_python.h" #include "port/oc_clock.h" #include "security/oc_obt_internal.h" @@ -29,10 +30,10 @@ #include "oc_streamlined_onboarding.h" #endif -#include #if defined(_WIN32) #include #elif defined(__linux__) +#include #include #else #error "Unsupported OS" @@ -47,14 +48,6 @@ #define MAX_NUM_RT (50) #define MAX_URI_LENGTH (30) -/* Structure in app to track currently discovered owned/unowned devices */ -typedef struct device_handle_t -{ - struct device_handle_t *next; - oc_uuid_t uuid; - char device_name[64]; -} device_handle_t; - /* Pool of device handles */ OC_MEMB(device_handles, device_handle_t, MAX_OWNED_DEVICES); /* List of known owned devices */ @@ -92,18 +85,6 @@ static struct timespec ts; #endif static int quit = 0; -/** - * callback prototype to inform python layer that the onboarded/unonboarded list - * have changed - * - */ -typedef void (*changedCB)(char *uuid, char *state, char *event); -typedef void (*diplomatCB)(char *anchor, char *uri, char *state, char *event, - char *target, char *target_cred); -typedef void (*resourceCB)(char *anchor, char *uri, char *types, - char *interfaces); -typedef void (*clientCB)(char *uuid, char *state, char *event); - /** * structure with the callback * @@ -156,10 +137,6 @@ stringFromResponse(int code) return strings[code]; } -/** - * function to install callbacks, called from python - * - */ void install_changedCB(changedCB changedCB) { @@ -167,10 +144,6 @@ install_changedCB(changedCB changedCB) my_CBFunctions.changedFCB = changedCB; } -/** - * function to install diplomat callbacks, called from python - * - */ void install_diplomatCB(diplomatCB diplomatCB) { @@ -178,20 +151,13 @@ install_diplomatCB(diplomatCB diplomatCB) my_CBFunctions.diplomatFCB = diplomatCB; } -/** - * function to install resource callbacks, called from python - * - */ void install_resourceCB(resourceCB resourceCB) { PRINT("[C]install_resourceCB\n"); my_CBFunctions.resourceFCB = resourceCB; } -/** - * function to install client callbacks, called from python - * - */ + void install_clientCB(clientCB clientCB) { @@ -199,10 +165,6 @@ install_clientCB(clientCB clientCB) my_CBFunctions.clientFCB = clientCB; } -/** - * function to call the callback to python. - * - */ void inform_python(const char *uuid, const char *state, const char *event) { @@ -224,10 +186,6 @@ inform_resource_python(const char *anchor, const char *uri, const char *types, } } -/** - * function to print the returned cbor as JSON - * - */ void print_rep(oc_rep_t *rep, bool pretty_print) { @@ -247,10 +205,6 @@ get_response_payload() return response_payload; } -/** - * function to save the returned cbor as JSON - * - */ void save_rep(oc_rep_t *rep, bool pretty_print) { @@ -260,9 +214,6 @@ save_rep(oc_rep_t *rep, bool pretty_print) oc_rep_to_json(rep, response_payload, json_size + 1, pretty_print); } -/* function to call the callback for diplomats to python. - * - */ void inform_diplomat_python(const char *anchor, const char *uri, const char *state, const char *event, const char *target, @@ -276,10 +227,6 @@ inform_diplomat_python(const char *anchor, const char *uri, const char *state, } } -/** - * function to call the callback for clients to python. - * - */ void inform_client_python(const char *uuid, const char *state, const char *event) { @@ -289,10 +236,6 @@ inform_client_python(const char *uuid, const char *state, const char *event) } } -/** - * function to convert the uuid to the device handle - * - */ device_handle_t * py_getdevice_from_uuid(char *uuid, int owned) { @@ -360,10 +303,6 @@ signal_event_loop(void) #endif } -/** - * function to quit the event loop - * - */ void python_exit(int signal) { @@ -500,10 +439,7 @@ empty_device_list(oc_list_t list) /* End of app utility functions */ /* App invocations of oc_obt APIs */ -/** - * CB function on getting the device data. - * generic callback for owned/unowned devices - */ + bool cb_result = false; bool get_cb_result() @@ -777,7 +713,6 @@ otm_just_works_cb(oc_uuid_t *uuid, int status, void *data) } } -// function to list the unowned devices in iotivity (printed in C) void py_list_unowned_devices(void) { @@ -794,7 +729,6 @@ py_list_unowned_devices(void) } } -// function to list the owned devices in iotivity (printed in C) void py_list_owned_devices(void) { @@ -1039,7 +973,6 @@ delete_cred_by_credid_cb(int status, void *data) /** * function to handle the reset - * */ static void reset_device_cb(oc_uuid_t *uuid, int status, void *data) @@ -1067,20 +1000,12 @@ reset_device_cb(oc_uuid_t *uuid, int status, void *data) } } -/** - * function to retrieve the # owned devices - * - */ int py_get_nr_owned_devices(void) { return (oc_list_length(owned_devices)); } -/** - * function to retrieve the uuid of the owned/unowned device - * - */ char xx_di[OC_UUID_LEN]; char * get_uuid(int owned, int index) @@ -1104,10 +1029,6 @@ get_uuid(int owned, int index) return " empty "; } -/** - * function to retrieve the device name of the owned/unowned device - * - */ char * get_device_name(int owned, int index) { @@ -1131,10 +1052,6 @@ get_device_name(int owned, int index) return " empty "; } -/** - * function to retrieve the device name belonging to the uuid - * - */ char * get_device_name_from_uuid(char *uuid) { @@ -1165,20 +1082,12 @@ get_device_name_from_uuid(char *uuid) return " empty "; } -/** - * function to retrieve the number of unowned device - * - */ int py_get_nr_unowned_devices(void) { return (oc_list_length(unowned_devices)); } -/** - * function to reset the owned device - * - */ void py_reset_device(char *uuid) { @@ -2536,7 +2445,11 @@ python_main(void) display_device_uuid(); while (quit != 1) { +#if defined(_WIN32) + Sleep(5000); +#elif defined(__linux__) sleep(5); +#endif } #if defined(_WIN32) diff --git a/python/oc_python.h b/python/oc_python.h new file mode 100644 index 0000000000..c73935f51d --- /dev/null +++ b/python/oc_python.h @@ -0,0 +1,349 @@ +/* +// Copyright (c) 2017-2019 Intel Corporation +// (c) 2021 Cascoda Ltd. +// (c) 2021 Cable Televesion Laboratories Ltd. + +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#ifndef OC_PYTHON_H +#define OC_PYTHON_H + +#include "oc_api.h" +#include "oc_export.h" + +#include + +/** + * callback prototypes to inform python layer that the onboarded/unonboarded + * list has changed + */ +typedef void (*changedCB)(char *uuid, char *state, char *event); +typedef void (*diplomatCB)(char *anchor, char *uri, char *state, char *event, + char *target, char *target_cred); +typedef void (*resourceCB)(char *anchor, char *uri, char *types, + char *interfaces); +typedef void (*clientCB)(char *uuid, char *state, char *event); + +/* Structure in app to track currently discovered owned/unowned devices */ +typedef struct device_handle_t +{ + struct device_handle_t *next; + oc_uuid_t uuid; + char device_name[64]; +} device_handle_t; + +/** + * function to install callbacks, called from python + */ +OC_API +void install_changedCB(changedCB changedCB); + +/** + * function to install diplomat callbacks, called from python + */ +OC_API +void install_diplomatCB(diplomatCB diplomatCB); + +/** + * function to install resource callbacks, called from python + */ +OC_API +void install_resourceCB(resourceCB resourceCB); + +/** + * function to install client callbacks, called from python + */ +OC_API +void install_clientCB(clientCB clientCB); + +/** + * function to call the callback to python. + */ +OC_API +void inform_python(const char *uuid, const char *state, const char *event); + +OC_API +void inform_resource_python(const char *anchor, const char *uri, + const char *types, const char *interfaces); + +/** + * function to print the returned cbor as JSON + */ +OC_API +void print_rep(oc_rep_t *rep, bool pretty_print); + +OC_API +char *get_response_payload(); + +/** + * function to save the returned cbor as JSON + */ +OC_API +void save_rep(oc_rep_t *rep, bool pretty_print); + +/** + * function to call the callback for diplomats to python. + */ +OC_API +void inform_diplomat_python(const char *anchor, const char *uri, + const char *state, const char *event, + const char *target, const char *target_cred); + +/** + * function to call the callback for clients to python. + */ +OC_API +void inform_client_python(const char *uuid, const char *state, + const char *event); + +/** + * function to convert the uuid to the device handle + */ +OC_API +device_handle_t *py_getdevice_from_uuid(char *uuid, int owned); + +/** + * function to quit the event loop + */ +OC_API +void python_exit(int signal); + +/* App utility functions */ + +OC_API +void empty_device_list(oc_list_t list); + +/* End of app utility functions */ + +/* App invocations of oc_obt APIs */ + +/** + * CB function on getting the device data. + * generic callback for owned/unowned devices + */ +OC_API +bool get_cb_result(); + +OC_API +void discover_owned_devices(int scope); + +OC_API +void discover_unowned_devices(int scope); + +OC_API +void py_discover_unowned_devices(int scope); + +OC_API +void py_otm_rdp(char *uuid, char *pin); + +OC_API +void py_request_random_pin(char *uuid); + +#ifdef OC_PKI +OC_API +void otm_cert_cb(oc_uuid_t *uuid, int status, void *data); +#endif /* OC_PKI */ + +// function to list the unowned devices in iotivity (printed in C) +OC_API +void py_list_unowned_devices(void); + +// function to list the owned devices in iotivity (printed in C) +OC_API +void py_list_owned_devices(void); + +OC_API +void py_otm_just_works(char *uuid); + +OC_API +void py_retrieve_acl2(char *uuid); + +OC_API +void display_cred_rsrc(oc_sec_creds_t *creds); + +OC_API +void retrieve_cred_rsrc_cb(oc_sec_creds_t *creds, void *data); + +OC_API +void retrieve_own_creds(void); + +OC_API +void delete_ace_by_aceid_cb(int status, void *data); + +OC_API +void delete_cred_by_credid_cb(int status, void *data); + +/** + * function to retrieve the # owned devices + */ +OC_API +int py_get_nr_owned_devices(void); + +/** + * function to retrieve the uuid of the owned/unowned device + */ +OC_API +char *get_uuid(int owned, int index); + +/** + * function to retrieve the device name of the owned/unowned device + */ +OC_API +char *get_device_name(int owned, int index); + +/** + * function to retrieve the device name belonging to the uuid + */ +OC_API +char *get_device_name_from_uuid(char *uuid); + +/** + * function to retrieve the number of unowned device + */ +OC_API +int py_get_nr_unowned_devices(void); + +/** + * function to reset the owned device + */ +OC_API +void py_reset_device(char *uuid); + +#ifdef OC_PKI +OC_API +void py_provision_id_cert(char *uuid); + +OC_API +void py_provision_role_cert(char *uuid, char *role, char *auth); + +OC_API +void provision_role_wildcard_ace_cb(oc_uuid_t *uuid, int status, void *data); +#endif /* OC_PKI */ + +#ifdef OC_OSCORE +OC_API +void provision_group_context_cb(oc_uuid_t *uuid, int status, void *data); + +OC_API +void provision_oscore_contexts_cb(int status, void *data); +#endif /* OC_OSCORE */ + +OC_API +void py_provision_pairwise_credentials(char *uuid1, char *uuid2); + +OC_API +void provision_authcrypt_wildcard_ace_cb(oc_uuid_t *uuid, int status, + void *data); + +OC_API +void py_provision_ace_cloud_access(char *uuid); + +OC_API +void py_provision_ace_d2dserverlist(char *uuid); + +OC_API +void py_provision_ace_device_resources(char *device_uuid, char *subject_uuid); + +OC_API +void py_provision_ace2(char *target, char *subject, char *href, char *crudn); + +#if defined(OC_SECURITY) && defined(OC_PKI) +OC_API +int read_pem(const char *file_path, char *buffer, size_t *buffer_len); +#endif /* OC_SECURITY && OC_PKI */ + +#ifdef OC_PKI +OC_API +void install_trust_anchor(void); +#endif /* OC_PKI */ + +OC_API +void set_sd_info(); + +#ifdef OC_CLOUD +OC_API +void py_provision_cloud_config_info(char *uuid, char *cloud_access_token, + char *cloud_apn, char *cloud_cis, + char *cloud_id); + +OC_API +void trustanchorcb(int status, void *data); + +OC_API +void py_provision_cloud_trust_anchor(char *uuid, char *cloud_id, + char *cloud_trust_anchor); + +OC_API +void py_retrieve_d2dserverlist(char *uuid); + +OC_API +void py_post_d2dserverlist(char *cloud_proxy_uuid, char *query); +#endif /* OC_CLOUD */ + +OC_API +void py_general_get(char *uuid, char *url); + +OC_API +void py_general_post(char *uuid, char *query, char *url, + char **payload_properties, char **payload_values, + char **payload_types, int array_size); + +OC_API +void factory_presets_cb(size_t device, void *data); + +OC_API +void py_discover_resources(char *uuid); + +OC_API +void py_post(char *uri, int value); + +OC_API +void display_device_uuid(); + +OC_API +char *py_get_obt_uuid(); + +OC_API +void test_print(void); + +#ifdef OC_SO +OC_API +void discover_diplomat_for_observe(void); + +OC_API +void py_diplomat_set_observe(char *state); + +OC_API +void py_diplomat_stop_observe(char *uuid); + +OC_API +void py_discover_diplomat_for_observe(void); +#endif /* OC_SO */ + +#ifdef OC_CLIENT +OC_API +void discover_doxm(void); + +OC_API +void discover_resource(char *rt, char *uuid); + +OC_API +void change_light(int value); +#endif /* OC_CLIENT */ + +OC_API +int python_main(void); + +#endif /* OC_PYTHON_H */ diff --git a/swig/swig_interfaces/oc_random.i b/swig/swig_interfaces/oc_random.i index 1759e091b8..28a279b957 100644 --- a/swig/swig_interfaces/oc_random.i +++ b/swig/swig_interfaces/oc_random.i @@ -20,4 +20,5 @@ %rename (randomValue) oc_random_value; %rename (destroy) oc_random_destroy; +#define OC_API %include "port/oc_random.h" \ No newline at end of file diff --git a/swig/swig_interfaces/oc_uuid.i b/swig/swig_interfaces/oc_uuid.i index bd2e4943f1..e8407e1fe3 100644 --- a/swig/swig_interfaces/oc_uuid.i +++ b/swig/swig_interfaces/oc_uuid.i @@ -97,4 +97,5 @@ oc_uuid_t * jni_gen_uuid() } %} +#define OC_API %include oc_uuid.h \ No newline at end of file