/** | |
* @file at_thread.c | |
* @brief Implementation of at_thread.c. | |
* | |
* Copyright (C) 2022 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 <pthread.h> | |
#include <sys/prctl.h> | |
#include <sys/ipc.h> | |
#include <errno.h> | |
#include "atreg_common.h" | |
#include "message.h" | |
#include "softap_log.h" | |
#include "atreg_msg.h" | |
/******************************************************************************* | |
* Macro definitions * | |
*******************************************************************************/ | |
/******************************************************************************* | |
* Type definitions * | |
*******************************************************************************/ | |
/******************************************************************************* | |
* Local variable definitions * | |
*******************************************************************************/ | |
/******************************************************************************* | |
* Global variable definitions * | |
*******************************************************************************/ | |
/******************************************************************************* | |
* Local function declarations * | |
*******************************************************************************/ | |
/******************************************************************************* | |
* Local function implementations * | |
*******************************************************************************/ | |
static void atreg_ser_regist_rsp_proc(struct atreg_msg_t *patreg_msgdata) | |
{ | |
struct atreg_ser_instance_t *patreg_ser_instance = NULL; | |
if (0 == patreg_msgdata->res) { | |
patreg_ser_instance = (struct atreg_ser_instance_t *)atreg_search_instance_tmp_by_reqid(patreg_msgdata->req_msg_id, AT_REG_SER); | |
if (NULL != patreg_ser_instance) { | |
pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock_tmp); | |
list_del((struct list_head *)patreg_ser_instance); | |
pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock_tmp); | |
pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock); | |
list_add_tail((struct list_head *)patreg_ser_instance, &atreg_ser_ctx.at_ser_list); | |
pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
slog(ATREG_PRINT, SLOG_NORMAL, "AT %s regist success!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
} else { | |
patreg_ser_instance = (struct atreg_ser_instance_t *)atreg_search_instance_tmp_by_reqid(patreg_msgdata->req_msg_id, AT_REG_SER); | |
pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock_tmp); | |
list_del((struct list_head *)patreg_ser_instance); | |
pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock_tmp); | |
slog(ATREG_PRINT, SLOG_ERR, "AT %s regist fail!\n", patreg_msgdata->at_cmd_prefix); | |
free(patreg_ser_instance); | |
} | |
return; | |
} | |
static void atreg_info_regist_rsp_proc(struct atreg_msg_t *patreg_msgdata) | |
{ | |
struct atreg_info_instance_t *patreg_info_instance = NULL; | |
if (0 == patreg_msgdata->res) { | |
patreg_info_instance = (struct atreg_info_instance_t *)atreg_search_instance_tmp_by_reqid(patreg_msgdata->req_msg_id, AT_REG_INFO); | |
if (NULL != patreg_info_instance) { | |
pthread_mutex_lock(&atreg_info_ctx.at_info_lock_tmp); | |
list_del((struct list_head *)patreg_info_instance); | |
pthread_mutex_unlock(&atreg_info_ctx.at_info_lock_tmp); | |
pthread_mutex_lock(&atreg_info_ctx.at_info_lock); | |
list_add_tail((struct list_head *)patreg_info_instance, &atreg_info_ctx.at_info_list); | |
pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
slog(ATREG_PRINT, SLOG_NORMAL, "AT %s regist success!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
} else { | |
patreg_info_instance = (struct atreg_info_instance_t *)atreg_search_instance_tmp_by_reqid(patreg_msgdata->req_msg_id, AT_REG_INFO); | |
pthread_mutex_lock(&atreg_info_ctx.at_info_lock_tmp); | |
list_del((struct list_head *)patreg_info_instance); | |
pthread_mutex_unlock(&atreg_info_ctx.at_info_lock_tmp); | |
slog(ATREG_PRINT, SLOG_ERR, "AT %s regist fail!\n", patreg_msgdata->at_cmd_prefix); | |
free(patreg_info_instance); | |
} | |
return; | |
} | |
static void atreg_regist_rsp_proc(unsigned char *aucDataBuf) | |
{ | |
struct atreg_msg_t *patreg_msgdata = (struct atreg_msg_t *)aucDataBuf; | |
switch (patreg_msgdata->type) { | |
case AT_REG_SER: | |
atreg_ser_regist_rsp_proc(patreg_msgdata); | |
break; | |
case AT_REG_INFO: | |
atreg_info_regist_rsp_proc(patreg_msgdata); | |
break; | |
default: | |
break; | |
} | |
sem_post(&atreg_common_ctx.sem_id); | |
return; | |
} | |
static void atreg_ser_unregist_rsp_proc(struct atreg_msg_t *patreg_msgdata) | |
{ | |
int i = -1; | |
int j = -1; | |
struct atreg_ser_instance_t *patreg_ser_instance = NULL; | |
if (0 == patreg_msgdata->res) { | |
patreg_ser_instance = (struct atreg_ser_instance_t *)atreg_search_instance_by_prefix(patreg_msgdata->at_cmd_prefix, AT_REG_SER); | |
if (NULL != patreg_ser_instance) { | |
pthread_mutex_lock(&atreg_ser_ctx.at_ser_idpool_lock); | |
i = patreg_ser_instance->req_msg_id / 8; | |
j = patreg_ser_instance->req_msg_id % 8; | |
atreg_ser_dynamic_idpool[i] = atreg_ser_dynamic_idpool[i] & (~(1 << (7 - j))); | |
atreg_ser_dynamic_idpool[i] = atreg_ser_dynamic_idpool[i] & (~(1 << (6 - j))); | |
pthread_mutex_unlock(&atreg_ser_ctx.at_ser_idpool_lock); | |
pthread_mutex_lock(&atreg_ser_ctx.at_ser_lock); | |
list_del((struct list_head *)patreg_ser_instance); | |
pthread_mutex_unlock(&atreg_ser_ctx.at_ser_lock); | |
free(patreg_ser_instance); | |
slog(ATREG_PRINT, SLOG_NORMAL, "AT %s unregist success!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
} else { | |
slog(ATREG_PRINT, SLOG_ERR, "AT %s unregist fail!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
return; | |
} | |
static void atreg_info_unregist_rsp_proc(struct atreg_msg_t *patreg_msgdata) | |
{ | |
int i = -1; | |
int j = -1; | |
struct atreg_info_instance_t *patreg_info_instance = NULL; | |
if (0 == patreg_msgdata->res) { | |
patreg_info_instance = (struct atreg_info_instance_t *)atreg_search_instance_by_prefix(patreg_msgdata->at_cmd_prefix, AT_REG_INFO); | |
if (NULL != patreg_info_instance) { | |
pthread_mutex_lock(&atreg_info_ctx.at_info_idpool_lock); | |
i = (patreg_info_instance->req_msg_id - 512) / 8; | |
j = (patreg_info_instance->req_msg_id -512) % 8; | |
atreg_info_dynamic_idpool[i] = atreg_info_dynamic_idpool[i] & (~(1 << (7 - j))); | |
pthread_mutex_unlock(&atreg_info_ctx.at_info_idpool_lock); | |
pthread_mutex_lock(&atreg_info_ctx.at_info_lock); | |
list_del((struct list_head *)patreg_info_instance); | |
pthread_mutex_unlock(&atreg_info_ctx.at_info_lock); | |
free(patreg_info_instance); | |
slog(ATREG_PRINT, SLOG_NORMAL, "AT %s unregist success!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
} else { | |
slog(ATREG_PRINT, SLOG_ERR, "AT %s unregist fail!\n", patreg_msgdata->at_cmd_prefix); | |
} | |
return; | |
} | |
static void atreg_unregist_rsp_proc(unsigned char *aucDataBuf) | |
{ | |
struct atreg_msg_t *patreg_msgdata = (struct atreg_msg_t *)aucDataBuf; | |
switch (patreg_msgdata->type) { | |
case AT_REG_SER: | |
atreg_ser_unregist_rsp_proc(patreg_msgdata); | |
break; | |
case AT_REG_INFO: | |
atreg_info_unregist_rsp_proc(patreg_msgdata); | |
break; | |
default: | |
break; | |
} | |
sem_post(&atreg_common_ctx.sem_id); | |
return; | |
} | |
static void atreg_ser_cb_proc(void *patreg_instance, unsigned char *aucDataBuf) | |
{ | |
int send_ret = -1; | |
unsigned char res_msg[MAX_MSG_LEN] = {0}; | |
struct atreg_ser_instance_t *patreg_ser_instance = (struct atreg_ser_instance_t *)patreg_instance; | |
patreg_ser_instance->cb(aucDataBuf, res_msg); | |
send_ret = ipc_send_message2(atreg_common_ctx.modid, MODULE_ID_AT_CTL, patreg_ser_instance->rsp_msg_id, sizeof(res_msg), (unsigned char *)res_msg, 0); | |
if (0 != send_ret) { | |
slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_ser_cb_proc ipc fail!\n"); | |
} | |
return; | |
} | |
static void atreg_info_cb_proc(void *patreg_instance, unsigned char *aucDataBuf) | |
{ | |
struct atreg_info_instance_t *patreg_info_instance = (struct atreg_info_instance_t *)patreg_instance; | |
patreg_info_instance->cb(aucDataBuf); | |
return; | |
} | |
static void atreg_cb_proc(int req_msg_id, unsigned char *aucDataBuf) | |
{ | |
struct atreg_instance_and_type_t atreg_instance_and_type = {0}; | |
atreg_instance_and_type = atreg_search_instance_and_type_by_reqid(req_msg_id); | |
switch (atreg_instance_and_type.type) { | |
case AT_REG_SER: | |
atreg_ser_cb_proc(atreg_instance_and_type.instance, aucDataBuf); | |
break; | |
case AT_REG_INFO: | |
atreg_info_cb_proc(atreg_instance_and_type.instance, aucDataBuf); | |
break; | |
default: | |
break; | |
} | |
return; | |
} | |
static void atreg_msg_proc(MSG_BUF *msg) | |
{ | |
if(NULL == msg) { | |
slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_msg_proc the msg is NULL!\n"); | |
return; | |
} | |
switch(msg->usMsgCmd) { | |
case MSG_CMD_AT_REG_RSP: | |
atreg_regist_rsp_proc(msg->aucDataBuf); | |
break; | |
case MSG_CMD_AT_UNREG_RSP: | |
atreg_unregist_rsp_proc(msg->aucDataBuf); | |
break; | |
default: | |
atreg_cb_proc(msg->usMsgCmd, msg->aucDataBuf); | |
break; | |
} | |
return; | |
} | |
/******************************************************************************* | |
* Global function implementations * | |
*******************************************************************************/ | |
/** ¸ÃÏ̴߳´½¨Ö®ºó£¬½«²»»áÍ˳ö */ | |
void atreg_msg_thread_entry(void *arg) | |
{ | |
struct atreg_common_context_t *patreg_common_ctx = (struct atreg_common_context_t *)arg; | |
int imsgq = -1; | |
int iret = 0; | |
MSG_BUF msgbuf; | |
long msgsize = sizeof(MSG_BUF) - sizeof(long); | |
char name[32] = {0}; | |
if(NULL == patreg_common_ctx) { | |
slog(ATREG_PRINT, SLOG_ERR, "Err: at_thread_entry the arg is NULL!\n"); | |
return; | |
} | |
snprintf(name, 31, "atreg%d", patreg_common_ctx->modid); | |
prctl(PR_SET_NAME, name, 0, 0, 0); | |
/* ´´½¨atregÏûÏ¢¶ÓÁÐ */ | |
imsgq = msgget(patreg_common_ctx->modid, IPC_CREAT|0600); | |
if (-1 == imsgq) { | |
slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_thread_entry msgget fail!\n"); | |
return; | |
} | |
while(1) { | |
memset(&msgbuf, 0, sizeof(MSG_BUF)); | |
iret = msgrcv(imsgq, &msgbuf, msgsize, 0, 0); | |
if (-1 == iret) { | |
slog(ATREG_PRINT, SLOG_ERR, "Err: atreg_thread_entry msgrcv errno=%s\n", errno); | |
continue; | |
} | |
atreg_msg_proc(&msgbuf); | |
} | |
slog(ATREG_PRINT, SLOG_NORMAL, "atreg_thread_entry the thread is stop!\n"); | |
} | |