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 fcc_bundle_common_utils.c Source File

fcc_bundle_common_utils.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //  
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //  
00008 //     http://www.apache.org/licenses/LICENSE-2.0
00009 //  
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 // ----------------------------------------------------------------------------
00016 #ifndef USE_TINY_CBOR
00017 #include "fcc_bundle_handler.h"
00018 #include "cn-cbor.h"
00019 #include "pv_error_handling.h"
00020 #include "fcc_bundle_utils.h"
00021 #include "fcc_malloc.h"
00022 #include "general_utils.h"
00023 #include "fcc_utils.h"
00024 #include "factory_configurator_client.h"
00025 
00026 #define  FCC_MAX_SIZE_OF_STRING 512
00027 
00028 /** Gets name from cbor struct.
00029 *
00030 * @param text_cb[in]          The cbor text structure
00031 * @param name_out[out]        The out buffer for string data
00032 * @param name_len_out[out]    The actual size of output buffer
00033 *
00034 * @return
00035 *     true for success, false otherwise.
00036 */
00037 static bool get_data_name(const cn_cbor *text_cb, uint8_t **name_out, size_t *name_len_out)
00038 {
00039     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00040     SA_PV_ERR_RECOVERABLE_RETURN_IF((text_cb == NULL), false, "Cbor pointer is NULL");
00041     SA_PV_ERR_RECOVERABLE_RETURN_IF((name_out == NULL), false, "Invalid pointer for name");
00042     SA_PV_ERR_RECOVERABLE_RETURN_IF((name_len_out == NULL), false, "Invalid pointer for name_len");
00043 
00044     *name_out = (uint8_t*)fcc_malloc((size_t)(text_cb->length));
00045     SA_PV_ERR_RECOVERABLE_RETURN_IF((*name_out == NULL), false, "Failed to allocate buffer for name");
00046 
00047     memcpy(*name_out, text_cb->v.bytes, (size_t)text_cb->length);
00048     *name_len_out = (size_t)text_cb->length;
00049     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00050 
00051     return true;
00052 }
00053 
00054 /** Gets data format from cbor struct
00055 *
00056 * The function goes over all formats and compares it with format from cbor structure.
00057 *
00058 * @param data_cb[in]         The cbor text structure
00059 * @param data_format[out]    The format of data
00060 *
00061 * @return
00062 *     true for success, false otherwise.
00063 */
00064 static bool get_data_format(const cn_cbor *data_cb, fcc_bundle_data_format_e *data_format)
00065 {
00066 
00067     int data_format_index;
00068     bool res;
00069 
00070     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00071     SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "data_cb is null");
00072     SA_PV_ERR_RECOVERABLE_RETURN_IF((data_format == NULL), false, "data_format is null");
00073     SA_PV_ERR_RECOVERABLE_RETURN_IF((*data_format != FCC_INVALID_DATA_FORMAT), false, "wrong data format value");
00074 
00075     for (data_format_index = 0; data_format_index < FCC_MAX_DATA_FORMAT - 1; data_format_index++) {
00076         res = is_memory_equal(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name,
00077                               strlen(fcc_bundle_data_format_lookup_table[data_format_index].data_format_name),
00078                               data_cb->v.bytes,
00079                               (size_t)(data_cb->length));
00080         if (res) {
00081             *data_format = fcc_bundle_data_format_lookup_table[data_format_index].data_format_type;
00082             return true;
00083         }
00084     }
00085     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00086     return false;
00087 }
00088 
00089 bool get_data_buffer_from_cbor(const cn_cbor *data_cb, uint8_t **out_data_buffer, size_t *out_size)
00090 {
00091 
00092     cn_cbor_type cb_type;
00093 
00094     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00095     SA_PV_ERR_RECOVERABLE_RETURN_IF((data_cb == NULL), false, "key_data_cb is null");
00096     SA_PV_ERR_RECOVERABLE_RETURN_IF((out_size == NULL), false, "Size buffer is null ");
00097     SA_PV_ERR_RECOVERABLE_RETURN_IF((out_data_buffer == NULL), false, "Data buffer is null");
00098     cb_type = data_cb->type;
00099 
00100     switch (cb_type) {
00101         case CN_CBOR_TAG:
00102             *out_data_buffer = (uint8_t*)data_cb->first_child->v.bytes;
00103             *out_size = (size_t)data_cb->first_child->length;
00104             break;
00105         case CN_CBOR_TEXT:
00106         case CN_CBOR_BYTES:
00107             *out_data_buffer = (uint8_t*)data_cb->v.bytes;
00108             *out_size = (size_t)(data_cb->length);
00109             break;
00110         case CN_CBOR_UINT:
00111             *out_data_buffer = (uint8_t*)(&(data_cb->v.uint));
00112             *out_size = (size_t)(data_cb->length);
00113             break;
00114         case CN_CBOR_INT:
00115             *out_data_buffer = (uint8_t*)(&(data_cb->v.sint));
00116             *out_size = (size_t)(data_cb->length);
00117             break;
00118         default:
00119             SA_PV_LOG_ERR("Invalid cbor data type (%u)!", data_cb->type);
00120             return false;
00121     }
00122     SA_PV_LOG_TRACE_FUNC_EXIT("out_size=%" PRIu32 "", (uint32_t)*out_size);
00123     return true;
00124 }
00125 /** Frees all allocated memory of data parameter struct and sets initial values.
00126 *
00127 * @param data_param[in/out]    The data parameter structure
00128 */
00129 void fcc_bundle_clean_and_free_data_param(fcc_bundle_data_param_s *data_param)
00130 {
00131     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00132 
00133     if (data_param->name != NULL) {
00134         fcc_free(data_param->name);
00135         data_param->name = NULL;
00136     }
00137 
00138     if (data_param->private_key_name != NULL) {
00139         fcc_free(data_param->private_key_name);
00140         data_param->private_key_name = NULL;
00141     }
00142 
00143     data_param->array_cn = NULL;
00144 
00145     //FIXME - in case we will support pem, add additional pointer data_der, that will point to allocated
00146     // memory and will always released in case not NULL nad data pointer will relate to user buffer allways.
00147     /*if (data_param->data_der != NULL) {
00148     fcc_stats_free(data_param->data_der);
00149     data_param->data_der = NULL;
00150     }*/
00151 
00152     memset(data_param, 0, sizeof(fcc_bundle_data_param_s));
00153     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00154 
00155 }
00156 bool fcc_bundle_get_data_param(const cn_cbor *data_param_cb, fcc_bundle_data_param_s *data_param)
00157 {
00158     bool status = false;
00159     int data_param_index = 0;
00160     cn_cbor *data_param_value_cb;
00161     fcc_bundle_data_param_type_e data_param_type;
00162 
00163     SA_PV_LOG_TRACE_FUNC_ENTER_NO_ARGS();
00164 
00165     //Prepare key struct
00166     fcc_bundle_clean_and_free_data_param(data_param);
00167 
00168     //Go over all key's parameters and extract it to appropriate key struct member
00169     for (data_param_index = FCC_BUNDLE_DATA_PARAM_NAME_TYPE; data_param_index < FCC_BUNDLE_DATA_PARAM_MAX_TYPE; data_param_index++) {
00170 
00171         //Get value of parameter
00172         data_param_value_cb = cn_cbor_mapget_string(data_param_cb, fcc_bundle_data_param_lookup_table[data_param_index].data_param_name);
00173 
00174         if (data_param_value_cb != NULL) {
00175             //Get type of parameter
00176             data_param_type = fcc_bundle_data_param_lookup_table[data_param_index].data_param_type;
00177 
00178             switch (data_param_type) {
00179                 case FCC_BUNDLE_DATA_PARAMETER_PRIVATE_KEY_NAME_TYPE:
00180                     status = get_data_name(data_param_value_cb, &(data_param->private_key_name), &(data_param->private_key_name_len));
00181                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get private key  name");
00182                     break;
00183 
00184                 case FCC_BUNDLE_DATA_PARAM_NAME_TYPE:
00185                     status = get_data_name(data_param_value_cb, &(data_param->name), &(data_param->name_len));
00186                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get data parameter name");
00187                     break;
00188 
00189                 case FCC_BUNDLE_DATA_PARAM_SCHEME_TYPE:
00190                     status = fcc_bundle_get_key_type(data_param_value_cb, (fcc_bundle_key_type_e*)&(data_param->type));
00191                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter type");
00192                     break;
00193 
00194                 case FCC_BUNDLE_DATA_PARAM_FORMAT_TYPE:
00195                     status = get_data_format(data_param_value_cb, (fcc_bundle_data_format_e*)&(data_param->format));
00196                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get key format");
00197                     break;
00198 
00199                 case FCC_BUNDLE_DATA_PARAM_DATA_TYPE:
00200                     status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->data), &(data_param->data_size));
00201                     data_param->data_type = FCC_EXTERNAL_BUFFER_TYPE;
00202                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get parameter data");
00203                     break;
00204                 case FCC_BUNDLE_DATA_PARAM_ARRAY_TYPE:
00205                     data_param->array_cn = data_param_value_cb;
00206                     break;
00207                 case FCC_BUNDLE_DATA_PARAM_ACL_TYPE:
00208                     status = get_data_buffer_from_cbor(data_param_value_cb, &(data_param->acl), &data_param->acl_size);
00209                     SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to get acl data");
00210                     break;
00211                 default:
00212                     SA_PV_ERR_RECOVERABLE_GOTO_IF((true), status = false, error_exit, "Parameter's field name is illegal");
00213             }//switch
00214         }//if
00215     }//for
00216 
00217     //FIXME: should be uncommented if PEM format is supported.
00218     /*
00219       if (data_param->format == FCC_PEM_DATA_FORMAT) {
00220           //status = convert_certificate_from_pem_to_der((uint8_t**)&(data_param->data), &(data_param->data_size));
00221           SA_PV_ERR_RECOVERABLE_GOTO_IF((status != true), status = false, error_exit, "Failed to convert the key from pem to der");
00222           //key->data_type = FCC_INTERNAL_BUFFER_TYPE;
00223       }
00224     */
00225 
00226     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00227     return status;
00228 
00229 error_exit:
00230     fcc_bundle_clean_and_free_data_param(data_param);
00231     SA_PV_LOG_TRACE_FUNC_EXIT_NO_ARGS();
00232     return false;
00233 }
00234 
00235 fcc_status_e  fcc_bundle_process_sotp_buffer(cn_cbor *cbor_bytes, sotp_type_e sotp_type)
00236 {
00237     uint8_t *buf;
00238     size_t buf_size;
00239     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00240     bool status;
00241     char *sotp_type_name;
00242     size_t sotp_type_name_size = 0;
00243 
00244     SA_PV_LOG_INFO_FUNC_ENTER_NO_ARGS();
00245     
00246     fcc_status = fcc_get_sotp_type_name(sotp_type, &sotp_type_name, &sotp_type_name_size);
00247     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_INVALID_PARAMETER,exit, "Failed to get sotp type name");
00248     SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_bytes->type != CN_CBOR_BYTES), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "cn_cbor object of incorrect type");
00249 
00250     status = get_data_buffer_from_cbor(cbor_bytes, &buf, &buf_size);
00251     SA_PV_ERR_RECOVERABLE_GOTO_IF((status == false), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor");
00252 
00253     fcc_status = fcc_sotp_data_store(buf, buf_size, sotp_type);
00254     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = FCC_STATUS_STORE_ERROR, exit, "Unable to store data to sotp");
00255 
00256 exit:
00257     if (fcc_status != FCC_STATUS_SUCCESS) {
00258         // In case of fcc_store_error_info failure we would still rather return the previous caught error.
00259         (void)fcc_store_error_info((const uint8_t*)sotp_type_name, sotp_type_name_size, fcc_status);
00260     }
00261     SA_PV_LOG_INFO_FUNC_EXIT_NO_ARGS();
00262     return fcc_status;
00263 }
00264 
00265 fcc_status_e  bundle_process_status_field(const cn_cbor *cbor_blob, char *cbor_group_name, size_t cbor_group_name_size, bool *fcc_field_status)
00266 {
00267     uint8_t *buff = NULL;
00268     size_t buff_size;
00269     uint32_t fcc_field_value;
00270     bool status;
00271     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00272 
00273     SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob == NULL), fcc_status = FCC_STATUS_INVALID_PARAMETER, exit, "Invalid param cbor_blob");
00274     SA_PV_ERR_RECOVERABLE_GOTO_IF((cbor_blob->type != CN_CBOR_UINT), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unexpected CBOR type");
00275 
00276     status = get_data_buffer_from_cbor(cbor_blob, &buff, &buff_size);
00277     SA_PV_ERR_RECOVERABLE_GOTO_IF((!status), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Unable to retrieve data from cn_cbor");
00278     SA_PV_ERR_RECOVERABLE_GOTO_IF((buff_size != sizeof(fcc_field_value)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit, "Incorrect buffer size for field value");
00279 
00280     memcpy(&fcc_field_value, buff, buff_size);
00281     SA_PV_ERR_RECOVERABLE_GOTO_IF(((fcc_field_value != 0) && (fcc_field_value != 1)), fcc_status = FCC_STATUS_BUNDLE_ERROR, exit,"Unexpected value, should be either 0 or 1");
00282 
00283     if (fcc_field_value == 1) {
00284         *fcc_field_status = true;
00285     }
00286     else {
00287         *fcc_field_status = false;
00288     }
00289 
00290 exit:
00291     if (fcc_status != FCC_STATUS_SUCCESS)
00292     {
00293         // In case of fcc_store_error_info failure we would still rather return the previous caught error.
00294         (void)fcc_store_error_info((const uint8_t*)cbor_group_name, cbor_group_name_size, fcc_status);
00295     }
00296     return fcc_status;
00297 }
00298 
00299 
00300 fcc_status_e  fcc_bundle_factory_disable( void )
00301 {
00302 
00303     fcc_status_e  fcc_status = FCC_STATUS_SUCCESS;
00304 
00305     fcc_status = fcc_factory_disable();
00306     SA_PV_ERR_RECOVERABLE_GOTO_IF((fcc_status != FCC_STATUS_SUCCESS), fcc_status = fcc_status, exit, "Failed to set factory disable flag");
00307 
00308 exit:
00309     if (fcc_status != FCC_STATUS_SUCCESS) {
00310         // In case of fcc_store_error_info failure we would still rather return the previous caught error.
00311         (void)fcc_store_error_info((const uint8_t*)g_sotp_factory_disable_type_name, strlen(g_sotp_factory_disable_type_name), fcc_status);
00312     }
00313     return fcc_status;
00314 }
00315 #endif