Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_uc_device_identity_kcm.c Source File

arm_uc_device_identity_kcm.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "pal4life-device-identity/pal_device_identity.h"
00020 #include "update-client-common/arm_uc_config.h"
00021 #include <stdint.h>
00022 
00023 #ifndef ARM_UC_USE_KCM
00024 #define ARM_UC_USE_KCM 0
00025 #endif
00026 
00027 #if ARM_UC_USE_KCM
00028 
00029 #include "key-config-manager/key_config_manager.h"
00030 
00031 #define SIZE_OF_GUID (sizeof(arm_uc_guid_t))
00032 // Hex encoded GUIDs with up to 4 hyphens.
00033 #define SIZE_OF_TEXT_GUID ((SIZE_OF_GUID) * 2 + 4)
00034 
00035 /* these defines are copied from:
00036    mbed-cloud-client/source/include/CloudClientStorage.h
00037 */
00038 #define KEY_DEVICE_MANUFACTURER_DEPRECATED      "mbed.Manufacturer"
00039 #define KEY_DEVICE_MODELNUMBER_DEPRECATED       "mbed.ModelNumber"
00040 #define KEY_ENDPOINT_NAME                       "mbed.EndpointName"
00041 #define KEY_VENDOR_ID                           "mbed.VendorId"
00042 #define KEY_CLASS_ID                            "mbed.ClassId"
00043 
00044 static arm_uc_error_t pal_kcm_internal_set_guid(const arm_uc_guid_t* guid,
00045                                                 const char* key,
00046                                                 size_t key_length)
00047 {
00048     arm_uc_error_t result = { .code = ERR_INVALID_PARAMETER };
00049 
00050     if (guid && key)
00051     {
00052         kcm_status_e  kcm_status = kcm_item_store((const uint8_t*) key,
00053                                                  key_length,
00054                                                  KCM_CONFIG_ITEM,
00055                                                  true,
00056                                                  (const uint8_t*) guid,
00057                                                  SIZE_OF_GUID,
00058                                                  NULL);
00059 
00060         if (kcm_status == KCM_STATUS_SUCCESS)
00061         {
00062             result.code = ERR_NONE;
00063         }
00064     }
00065 
00066     return result;
00067 }
00068 
00069 static arm_uc_error_t pal_kcm_internal_get_guid(arm_uc_guid_t* guid,
00070                                                 const char* key,
00071                                                 size_t key_length)
00072 {
00073     arm_uc_error_t result = { .module = TWO_CC('D', 'I'), .error = ERR_INVALID_PARAMETER };
00074 
00075     if (guid && key)
00076     {
00077         uint8_t buffer[SIZE_OF_GUID] = { 0 };
00078         size_t value_length = 0;
00079         memset(guid, 0, SIZE_OF_GUID);
00080 
00081         kcm_status_e  kcm_status = kcm_item_get_data((const uint8_t*) key,
00082                                         key_length,
00083                                         KCM_CONFIG_ITEM,
00084                                         buffer,
00085                                         SIZE_OF_GUID,
00086                                         &value_length);
00087         if (kcm_status == KCM_STATUS_ITEM_NOT_FOUND)
00088         {
00089             result.code = ARM_UC_DI_ERR_NOT_FOUND;
00090         }
00091 
00092         if (kcm_status == KCM_STATUS_SUCCESS)
00093         {
00094             result.code = ERR_NONE;
00095             memcpy(guid, buffer, SIZE_OF_GUID);
00096         }
00097     }
00098 
00099     return result;
00100 }
00101 
00102 static bool pal_kcm_internal_compare(const arm_uc_guid_t* guid,
00103                                      const arm_uc_buffer_t* buffer)
00104 {
00105     // count how many bytes match
00106     uint8_t index = 0;
00107 
00108     if (guid && buffer)
00109     {
00110         for ( ; (index < sizeof(arm_uc_guid_t)) && (index < buffer->size); index++)
00111         {
00112             // printf("%02X %02X\r\n", ((uint8_t*) guid)[index], buffer->ptr[index]);
00113 
00114             if (((uint8_t*) guid)[index] != buffer->ptr[index])
00115             {
00116                 break;
00117             }
00118         }
00119     }
00120 
00121     // return true if all bytes matched
00122     return (index == sizeof(arm_uc_guid_t));
00123 }
00124 
00125 /**
00126  * @brief Function for setting the vendor GUID.
00127  * @details The GUID is copied.
00128  * @param guid Pointer to a arm_uc_guid_t GUID.
00129  * @param copy Boolean value indicating whether the value should be copied or
00130  *             referenced.
00131  * @return Error code.
00132  */
00133 arm_uc_error_t pal_kcm_setVendorGuid(const arm_uc_guid_t* guid)
00134 {
00135     return pal_kcm_internal_set_guid(guid,
00136                                      KEY_VENDOR_ID,
00137                                      sizeof(KEY_VENDOR_ID) - 1);
00138 }
00139 
00140 /**
00141  * @brief Function for getting a pointer to the vendor GUID.
00142  * @param guid Pointer to a arm_uc_guid_t pointer.
00143  * @return Error code.
00144  */
00145 arm_uc_error_t pal_kcm_getVendorGuid(arm_uc_guid_t* guid)
00146 {
00147     arm_uc_error_t err = pal_kcm_internal_get_guid(guid,
00148                                     KEY_VENDOR_ID,
00149                                     sizeof(KEY_VENDOR_ID) - 1);
00150     if (err.code == ARM_UC_DI_ERR_NOT_FOUND)
00151     {
00152         err = pal_kcm_internal_get_guid(guid,
00153                                     KEY_DEVICE_MANUFACTURER_DEPRECATED,
00154                                     sizeof(KEY_DEVICE_MANUFACTURER_DEPRECATED) - 1);
00155     }
00156     return err;
00157 }
00158 
00159 /**
00160  * @brief Function for setting the device class GUID.
00161  * @details The GUID is copied.
00162  * @param guid Pointer to a arm_uc_guid_t GUID.
00163  * @param copy Boolean value indicating whether the value should be copied or
00164  *             referenced.
00165  * @return Error code.
00166  */
00167 arm_uc_error_t pal_kcm_setClassGuid(const arm_uc_guid_t* guid)
00168 {
00169     return pal_kcm_internal_set_guid(guid,
00170                                      KEY_CLASS_ID,
00171                                      sizeof(KEY_CLASS_ID) - 1);
00172 }
00173 
00174 /**
00175  * @brief Function for getting a pointer to the device class GUID.
00176  * @param guid Pointer to a arm_uc_guid_t pointer.
00177  * @return Error code.
00178  */
00179 arm_uc_error_t pal_kcm_getClassGuid(arm_uc_guid_t* guid)
00180 {
00181     arm_uc_error_t err = pal_kcm_internal_get_guid(guid,
00182                                     KEY_CLASS_ID,
00183                                     sizeof(KEY_CLASS_ID) - 1);
00184     if (err.code == ARM_UC_DI_ERR_NOT_FOUND)
00185     {
00186         err = pal_kcm_internal_get_guid(guid,
00187                                     KEY_DEVICE_MODELNUMBER_DEPRECATED,
00188                                     sizeof(KEY_DEVICE_MODELNUMBER_DEPRECATED) - 1);
00189     }
00190     return err;
00191 }
00192 
00193 /**
00194  * @brief Function for setting the device GUID.
00195  * @details The GUID is copied.
00196  * @param guid Pointer to a arm_uc_guid_t GUID.
00197  * @param copy Boolean value indicating whether the value should be copied or
00198  *             referenced.
00199  * @return Error code.
00200  */
00201 arm_uc_error_t pal_kcm_setDeviceGuid(const arm_uc_guid_t* guid)
00202 {
00203     return pal_kcm_internal_set_guid(guid,
00204                                      KEY_ENDPOINT_NAME,
00205                                      sizeof(KEY_ENDPOINT_NAME) - 1);
00206 }
00207 
00208 /**
00209  * @brief Function for getting a pointer to the device GUID.
00210  * @param guid Pointer to a arm_uc_guid_t pointer.
00211  * @return Error code.
00212  */
00213 arm_uc_error_t pal_kcm_getDeviceGuid(arm_uc_guid_t* guid)
00214 {
00215     return pal_kcm_internal_get_guid(guid,
00216                                      KEY_ENDPOINT_NAME,
00217                                      sizeof(KEY_ENDPOINT_NAME) - 1);
00218 }
00219 
00220 
00221 /**
00222  * @brief Check whether the three GUIDs provided are valid on the device.
00223  * @details
00224  * @param vendor_buffer Buffer pointer to the Vendor GUID.
00225  * @param class_buffer  Buffer pointer to the device class GUID.
00226  * @param device_buffer Buffer pointer to the device GUID.
00227  * @param isValid     Pointer to the boolean return value.
00228  * @return Error code.
00229  */
00230 arm_uc_error_t pal_kcm_deviceIdentityCheck(const arm_uc_buffer_t* vendor_buffer,
00231                                            const arm_uc_buffer_t* class_buffer,
00232                                            const arm_uc_buffer_t* device_buffer)
00233 {
00234     arm_uc_error_t result = { .code = MFST_ERR_NULL_PTR };
00235 
00236     uint8_t parameters_set = 0;
00237     uint8_t parameters_ok = 0;
00238 
00239     /* check device - device is optional */
00240     if (device_buffer &&
00241         device_buffer->ptr &&
00242         (device_buffer->size > 0))
00243     {
00244         parameters_set++;
00245 
00246         arm_uc_guid_t guid = { 0 };
00247 
00248         arm_uc_error_t retval = pal_kcm_getDeviceGuid(&guid);
00249 
00250         if (retval.code == ERR_NONE)
00251         {
00252             bool is_same = pal_kcm_internal_compare(&guid, device_buffer);
00253 
00254             if (is_same)
00255             {
00256                 parameters_ok++;
00257             }
00258             else
00259             {
00260                 result.code = MFST_ERR_GUID_DEVICE;
00261             }
00262         }
00263     }
00264 
00265     /* check class - class is optional */
00266     if (class_buffer &&
00267         class_buffer->ptr &&
00268         (class_buffer->size > 0))
00269     {
00270         parameters_set++;
00271 
00272         arm_uc_guid_t guid = { 0 };
00273 
00274         arm_uc_error_t retval = pal_kcm_getClassGuid(&guid);
00275 
00276         if (retval.code == ERR_NONE)
00277         {
00278             bool is_same = pal_kcm_internal_compare(&guid, class_buffer);
00279 
00280             if (is_same)
00281             {
00282                 parameters_ok++;
00283             }
00284             else
00285             {
00286                 result.code = MFST_ERR_GUID_DEVCLASS;
00287             }
00288         }
00289     }
00290 
00291     /* check vendor - vendor is mandatory and has mask 0x10. */
00292     if (vendor_buffer &&
00293         vendor_buffer->ptr &&
00294         (vendor_buffer->size > 0))
00295     {
00296         parameters_set += 0x10;
00297 
00298         arm_uc_guid_t guid = { 0 };
00299 
00300         arm_uc_error_t retval = pal_kcm_getVendorGuid(&guid);
00301 
00302         if (retval.code == ERR_NONE)
00303         {
00304             bool is_same = pal_kcm_internal_compare(&guid, vendor_buffer);
00305 
00306             if (is_same)
00307             {
00308                 parameters_ok += 0x10;
00309             }
00310             else
00311             {
00312                 result.code = MFST_ERR_GUID_VENDOR;
00313             }
00314         }
00315     }
00316 
00317     /* Device ID checks out when:
00318         - vendor match and neither class nor device is passed
00319         - vendor and class match and no device is passed
00320         - vendor and device match and no class is passed
00321         - vendor and class and device match
00322     */
00323     if ((parameters_set >= 0x10) && (parameters_set == parameters_ok))
00324     {
00325         result.code = MFST_ERR_NONE;
00326     }
00327 
00328     return result;
00329 }
00330 
00331 const ARM_PAL_DEVICE_IDENTITY arm_uc_device_identity_kcm = {
00332     .SetVendorGuid          = pal_kcm_setVendorGuid,
00333     .GetVendorGuid          = pal_kcm_getVendorGuid,
00334     .SetClassGuid           = pal_kcm_setClassGuid,
00335     .GetClassGuid           = pal_kcm_getClassGuid,
00336     .SetDeviceGuid          = pal_kcm_setDeviceGuid,
00337     .GetDeviceGuid          = pal_kcm_getDeviceGuid,
00338     .DeviceIdentityCheck    = pal_kcm_deviceIdentityCheck
00339 };
00340 
00341 #endif // ARM_UC_USE_KCM