blob: 034c7447f85f8c36100467bbb7a203afc1999728 [file] [log] [blame]
/**
* @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[MSG_DATA_MAX_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, strlen(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");
}