diff options
Diffstat (limited to 'src/4a-hal-manager/4a-hal-manager-cb.c')
-rw-r--r-- | src/4a-hal-manager/4a-hal-manager-cb.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/src/4a-hal-manager/4a-hal-manager-cb.c b/src/4a-hal-manager/4a-hal-manager-cb.c new file mode 100644 index 0000000..32fbb25 --- /dev/null +++ b/src/4a-hal-manager/4a-hal-manager-cb.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author Jonathan Aillet <jonathan.aillet@iot.bzh> + * + * 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. + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <string.h> + +#include <wrap-json.h> + +#include <afb/afb-binding.h> + +#include "4a-hal-utilities-data.h" + +#include "4a-hal-manager-cb.h" + +/******************************************************************************* + * HAL Manager event handler function * + ******************************************************************************/ + +// TBD JAI : to implement +void HalMgrDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json_object *eventJ) +{ + AFB_API_WARNING(apiHandle, "Not implemented yet"); + // Use "4a-hal-manager-events.h" to handle events +} + +/******************************************************************************* + * HAL Manager verbs functions * + ******************************************************************************/ + +void HalMgrPing(afb_req_t request) +{ + static int count = 0; + + count++; + + AFB_REQ_NOTICE(request, "ping count = %d", count); + afb_req_success(request, json_object_new_int(count), NULL); + + return; +} + +void HalMgrLoaded(afb_req_t request) +{ + int requestJsonErr = 0, allHal = 0, verbose = 0; + + char cardIdString[32]; + + afb_api_t apiHandle; + struct HalMgrData *halMgrData; + struct HalData *currentHalData; + + json_object *requestJson, *requestAnswer, *apiObject; + + if(! (apiHandle = afb_req_get_api(request))) { + afb_req_fail(request, "api_handle", "Can't get hal manager api handle"); + return; + } + + halMgrData = (struct HalMgrData *) afb_api_get_userdata(apiHandle); + if(! halMgrData) { + afb_req_fail(request, "hal_manager_data", "Can't get hal manager data"); + return; + } + + currentHalData = halMgrData->halDataList; + + if(! currentHalData) { + afb_req_success(request, NULL, "No Hal Api loaded"); + return; + } + + requestAnswer = json_object_new_array(); + if(! requestAnswer) { + afb_req_fail(request, "json_answer", "Can't generate json answer"); + return; + } + + if(! (requestJson = afb_req_json(request))) + AFB_REQ_NOTICE(request, "Can't get request json"); + else + requestJsonErr = wrap_json_unpack(requestJson, "{s?:b s?:b}", "all", &allHal, "verbose", &verbose); + + while(currentHalData) { + if(allHal || currentHalData->status == HAL_STATUS_READY) { + // Case if request key is 'verbose' and value is bigger than 0 + if(! requestJsonErr && verbose) { + if(currentHalData->sndCardId >= 0) + snprintf(cardIdString, sizeof(cardIdString), "hw:%i", currentHalData->sndCardId); + else + snprintf(cardIdString, sizeof(cardIdString), "not-found"); + + wrap_json_pack(&apiObject, + "{s:s s:i s:s s:i s:s s:s s:s s:s s:s}", + "api", currentHalData->apiName, + "status", (int) currentHalData->status, + "sndcard", currentHalData->sndCardPath, + "internal", (int) currentHalData->internal, + "info", currentHalData->info ? currentHalData->info : "", + "author", currentHalData->author ? currentHalData->author : "", + "version", currentHalData->version ? currentHalData->version : "", + "date", currentHalData->date ? currentHalData->date : "", + "snd-dev-id", cardIdString); + json_object_array_add(requestAnswer, apiObject); + } + // Case if request is empty or not handled + else { + json_object_array_add(requestAnswer, json_object_new_string(currentHalData->apiName)); + } + } + + currentHalData = currentHalData->next; + } + + afb_req_success(request, requestAnswer, "Requested data"); +} + +void HalMgrLoad(afb_req_t request) +{ + int cardId = -1; + + char *apiName, *sndCardPath, *info = NULL, *author = NULL, *version = NULL, *date = NULL; + + afb_api_t apiHandle; + struct HalMgrData *halMgrData; + struct HalData *addedHal; + + json_object *requestJson, *apiReceivedMetadata; + + if(! (apiHandle = afb_req_get_api(request))) { + afb_req_fail(request, "api_handle", "Can't get hal manager api handle"); + return; + } + + halMgrData = (struct HalMgrData *) afb_api_get_userdata(apiHandle); + if(! halMgrData) { + afb_req_fail(request, "hal_manager_data", "Can't get hal manager data"); + return; + } + + if(! (requestJson = afb_req_json(request))) { + afb_req_fail(request, "request_json", "Can't get request json"); + return; + } + + if(! json_object_object_get_ex(requestJson, "metadata", &apiReceivedMetadata)) { + afb_req_fail(request, "api_metadata", "Can't get json metadata section to register external hal"); + return; + } + + if(wrap_json_unpack(apiReceivedMetadata, + "{s:s s:s s?:s s?:s s?:s s?:s s?:i}", + "api", &apiName, + "uid", &sndCardPath, + "info", &info, + "author", &author, + "version", &version, + "date", &date, + "snd-dev-id", &cardId)) { + afb_req_fail(request, "api_metadata", "Can't metadata of api to register"); + return; + } + + addedHal = HalUtlAddHalToHalList(&halMgrData->halDataList); + + addedHal->internal = 0; + // TBD JAI : initialize external to unavailable once event from external hal will be handled + addedHal->status = HAL_STATUS_READY; + + addedHal->apiName = strdup(apiName); + addedHal->sndCardPath = strdup(sndCardPath); + + if(info) + addedHal->info = strdup(info); + + if(author) + addedHal->author = strdup(author); + + if(version) + addedHal->version = strdup(version); + + if(date) + addedHal->date = strdup(date); + + addedHal->sndCardId = cardId; + + // TBD JAI: add subscription to this api status events, if subscription fails, remove hal from list + + afb_req_success(request, NULL, "Api successfully registered"); +} + +void HalMgrUnload(afb_req_t request) +{ + char *apiName; + + afb_api_t apiHandle; + struct HalMgrData *halMgrData; + struct HalData *halToRemove; + + json_object *requestJson; + + if(! (apiHandle = afb_req_get_api(request))) { + afb_req_fail(request, "api_handle", "Can't get hal manager api handle"); + return; + } + + halMgrData = (struct HalMgrData *) afb_api_get_userdata(apiHandle); + if(! halMgrData) { + afb_req_fail(request, "hal_manager_data", "Can't get hal manager data"); + return; + } + + if(! (requestJson = afb_req_json(request))) { + afb_req_fail(request, "request_json", "Can't get request json"); + return; + } + + if(wrap_json_unpack(requestJson, "{s:s}", "api", &apiName)) { + afb_req_fail(request, "requested_api", "Can't get api to remove"); + return; + } + + halToRemove = HalUtlSearchHalDataByApiName(&halMgrData->halDataList, apiName); + if(! halToRemove) { + afb_req_fail(request, "requested_api", "Can't find api to remove"); + return; + } + + if(halToRemove->internal) { + afb_req_fail(request, "requested_api", "Can't remove an internal hal"); + return; + } + + if(HalUtlRemoveSelectedHalFromList(&halMgrData->halDataList, halToRemove)) { + afb_req_fail(request, "unregister_error", "Didn't succeed to remove specified api"); + return; + } + + // TBD JAI: remove subscription to this api status events + + afb_req_success(request, NULL, "Api successfully unregistered"); +} + +// TBD JAI : to implement +void HalMgrSubscribeEvent(afb_req_t request) +{ + AFB_REQ_WARNING(request, "Not implemented yet"); + + afb_req_success(request, json_object_new_boolean(0), NULL); +} + +// TBD JAI : to implement +void HalMgrUnsubscribeEvent(afb_req_t request) +{ + AFB_REQ_WARNING(request, "Not implemented yet"); + + afb_req_success(request, json_object_new_boolean(0), NULL); +} |