| /** | |
| * @file atreg_common.c | |
| * @brief Implementation of the inter APIs of libatreg. | |
| * | |
| * Copyright (C) 2021 Sanechips Technology Co., Ltd. | |
| * @author | |
| * | |
| * This program is free software; you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License version 2 as | |
| * published by the Free Software Foundation. £¨±ØÑ¡£ºGPLv2 Licence£© | |
| * | |
| */ | |
| /******************************************************************************* | |
| * Include header files * | |
| *******************************************************************************/ | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include "atreg_common.h" | |
| #include "at_utils.h" | |
| /******************************************************************************* | |
| * Macro definitions * | |
| *******************************************************************************/ | |
| /******************************************************************************* | |
| * Type definitions * | |
| *******************************************************************************/ | |
| /******************************************************************************* | |
| * Local variable definitions * | |
| *******************************************************************************/ | |
| /******************************************************************************* | |
| * Global variable definitions * | |
| *******************************************************************************/ | |
| struct atreg_ser_context_t atreg_ser_ctx; | |
| struct atreg_info_context_t atreg_info_ctx; | |
| struct atreg_common_context_t atreg_common_ctx; | |
| /** ser - ¶¯Ì¬id³Ø, ·¶Î§: 0~511 */ | |
| unsigned char atreg_ser_dynamic_idpool[ATREG_SER_ID_MAX]; | |
| /** info - ¶¯Ì¬id³Ø, ·¶Î§: 512~768 */ | |
| unsigned char atreg_info_dynamic_idpool[ATREG_INFO_ID_MAX]; | |
| extern int atreg_ser_cxt_is_init; | |
| extern int atreg_info_cxt_is_init; | |
| /******************************************************************************* | |
| * Local function declarations * | |
| *******************************************************************************/ | |
| /******************************************************************************* | |
| * Local function implementations * | |
| *******************************************************************************/ | |
| static void *atreg_ser_search_instance_by_prefix_proc(char *at_cmd_prefix) | |
| { | |
| struct atreg_ser_instance_t * entry = NULL; | |
| pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock); | |
| list_for_each_entry(entry, &atreg_ser_ctx.at_ser_list, list) { | |
| if(0 == at_strncmp(at_cmd_prefix, entry->at_cmd_prefix, AT_CMD_PREFIX)) { | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
| return NULL; | |
| } | |
| static void *atreg_info_search_instance_by_prefix_proc(char *at_cmd_prefix) | |
| { | |
| struct atreg_info_instance_t * entry = NULL; | |
| pthread_mutex_lock(&atreg_info_ctx.at_info_lock); | |
| list_for_each_entry(entry, &atreg_info_ctx.at_info_list, list) { | |
| if(0 == at_strncmp(at_cmd_prefix, entry->at_cmd_prefix, AT_CMD_PREFIX)) { | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
| return NULL; | |
| } | |
| static void *atreg_ser_search_instance_by_reqid_proc(int req_msg_id) | |
| { | |
| struct atreg_ser_instance_t *entry = NULL; | |
| pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock); | |
| list_for_each_entry(entry, &atreg_ser_ctx.at_ser_list, list) { | |
| if(entry->req_msg_id == req_msg_id) { | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
| return NULL; | |
| } | |
| static void *atreg_info_search_instance_by_reqid_proc(int req_msg_id) | |
| { | |
| struct atreg_info_instance_t *entry = NULL; | |
| pthread_mutex_lock(&atreg_info_ctx.at_info_lock); | |
| list_for_each_entry(entry, &atreg_info_ctx.at_info_list, list) { | |
| if(entry->req_msg_id == req_msg_id) { | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
| return NULL; | |
| } | |
| static void *atreg_ser_search_instance_tmp_by_reqid_proc(int req_msg_id) | |
| { | |
| struct atreg_ser_instance_t *entry = NULL; | |
| pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock_tmp); | |
| list_for_each_entry(entry, &atreg_ser_ctx.at_ser_list_tmp, list) { | |
| if(entry->req_msg_id == req_msg_id) { | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock_tmp); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock_tmp); | |
| return NULL; | |
| } | |
| static void *atreg_info_search_instance_tmp_by_reqid_proc(int req_msg_id) | |
| { | |
| struct atreg_info_instance_t *entry = NULL; | |
| pthread_mutex_lock(&atreg_info_ctx.at_info_lock_tmp); | |
| list_for_each_entry(entry, &atreg_info_ctx.at_info_list_tmp, list) { | |
| if(entry->req_msg_id == req_msg_id) { | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock_tmp); | |
| return (void *)entry; | |
| } | |
| } | |
| pthread_mutex_unlock(&atreg_info_ctx.at_info_lock_tmp); | |
| return NULL; | |
| } | |
| /******************************************************************************* | |
| * Global function implementations * | |
| *******************************************************************************/ | |
| void atreg_wait_rsp(int msg_cmd) | |
| { | |
| int ret = -1; | |
| if (clock_gettime(CLOCK_REALTIME, &atreg_common_ctx.ts) == -1) { | |
| slog(ATREG_PRINT, SLOG_NORMAL, "atreg_wait_rsp clock_gettime fail.\n"); | |
| return; | |
| } | |
| atreg_common_ctx.ts.tv_sec += WAIT_RSP_TIMEOUT; | |
| while ((ret = sem_timedwait(&atreg_common_ctx.sem_id, &atreg_common_ctx.ts)) == -1 && errno == EINTR) | |
| continue; | |
| if(-1 == ret) { | |
| slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_wait_rsp wait msg(%x) timeout.\n", msg_cmd); | |
| } | |
| else { | |
| slog(ATREG_PRINT, SLOG_NORMAL, "atreg_wait_rsp post msg(%x) response.\n", msg_cmd); | |
| } | |
| return; | |
| } | |
| void *atreg_search_instance_by_prefix(char *at_cmd_prefix, int atreg_type) | |
| { | |
| void* patreg = NULL; | |
| switch (atreg_type) { | |
| case AT_REG_SER: | |
| patreg = atreg_ser_search_instance_by_prefix_proc(at_cmd_prefix); | |
| break; | |
| case AT_REG_INFO: | |
| patreg = atreg_info_search_instance_by_prefix_proc(at_cmd_prefix); | |
| break; | |
| default: | |
| break; | |
| } | |
| return patreg; | |
| } | |
| void *atreg_search_instance_tmp_by_reqid(int req_msg_id, int atreg_type) | |
| { | |
| void* patreg = NULL; | |
| switch (atreg_type) { | |
| case AT_REG_SER: | |
| patreg = atreg_ser_search_instance_tmp_by_reqid_proc(req_msg_id); | |
| break; | |
| case AT_REG_INFO: | |
| patreg = atreg_info_search_instance_tmp_by_reqid_proc(req_msg_id); | |
| break; | |
| default: | |
| break; | |
| } | |
| return patreg; | |
| } | |
| struct atreg_instance_and_type_t atreg_search_instance_and_type_by_reqid(int req_msg_id) | |
| { | |
| void* patreg = NULL; | |
| struct atreg_instance_and_type_t atreg_instance_and_type = {0}; | |
| if(atreg_ser_cxt_is_init) | |
| patreg = atreg_ser_search_instance_by_reqid_proc(req_msg_id); | |
| if (NULL != patreg) { | |
| atreg_instance_and_type.type = AT_REG_SER; | |
| atreg_instance_and_type.instance = patreg; | |
| return atreg_instance_and_type; | |
| } | |
| if(atreg_info_cxt_is_init) | |
| patreg = atreg_info_search_instance_by_reqid_proc(req_msg_id); | |
| if (NULL != patreg) { | |
| atreg_instance_and_type.type = AT_REG_INFO; | |
| atreg_instance_and_type.instance = patreg; | |
| return atreg_instance_and_type; | |
| } | |
| atreg_instance_and_type.type = -1; | |
| return atreg_instance_and_type; | |
| } | |