doubao_chat/apps/wifi_ipc/wifi/tutk_platform.c

790 lines
17 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "system/includes.h"
#include "action.h"
#include "server/net_server.h"
#include "IOTCAPIs.h"
#include "AVAPIs.h"
#include "P2PCam/AVIOCTRLDEFs.h"
#include "P2PCam/AVFRAMEINFO.h"
#include "video_rt_tutk.h"
#include "mssdp/mssdp.h"
#include "app_config.h"
int pthread_mutex_init(int *mutex, const int *attr)
{
OS_MUTEX *pmutex;
pmutex = (OS_MUTEX *)malloc(sizeof(OS_MUTEX));
if (pmutex == NULL) {
*mutex = 0;
return -1;
}
os_mutex_create(pmutex);
*mutex = (int)pmutex;
return 0;
}
int pthread_mutex_destroy(int *mutex)
{
if (mutex != NULL && ((void *)*mutex != NULL)) {
os_mutex_del((OS_MUTEX *)(*mutex), OS_DEL_ALWAYS);
free((void *)(*mutex));
*mutex = 0;
}
return 0;
}
int pthread_mutex_lock(int *mutex)
{
return os_mutex_pend((OS_MUTEX *)(*mutex), 0);
}
int pthread_mutex_unlock(int *mutex)
{
return os_mutex_post((OS_MUTEX *)(*mutex));
}
int usleep(unsigned int t)
{
os_time_dly(t / 10000);
return 0;
}
#if 1
/***最大客户端数量***/
#define MAX_CLIENT_NUMBER 3
#define CMD_CHANNEL 0x0
#define FILE_CHANNEL 0x1
struct tutk_info {
struct list_head head;
u8 cli_num;
OS_MUTEX mutex;//用于保护客户端链表
u8 kill_task;
int login_pid;
u32 inited;
char username[64];
char password[64];
};
#define TEST_UID "HH25H2GNP4DTECTK111A"
//外部引用
void __cmd_pro(void *cli, const char *content);
enum {
TUTK_CMD_TIMEOUT = 0x1,
TUTK_ERR = 0x2,
TUTK_KILL_TASK = 0xff,
};
u32 OSTimeGet()
{
return OSGetTime();
}
static struct tutk_info tinfo;
static void tutk_login_info_cb(unsigned int nLoginInfo)
{
if ((nLoginInfo & 0x04)) {
printf("I can be connected via Internet\n");
} else if ((nLoginInfo & 0x08)) {
printf("I am be banned by IOTC Server because UID multi-login\n");
}
printf("loginInfo:0x%x\n", nLoginInfo);
}
static void tutk_login_task(void *arg)
{
int cnt = 0;
int ret = 0;
puts("\n thread_Login \n");
while (1) {
if (tinfo.kill_task) {
break;
}
ret = IOTC_Device_Login(TEST_UID, "aaaa", "12345678");
if (ret == IOTC_ER_NoERROR) {
printf("tutk platform login success !@!!\n");
//os_time_dly(100);
} else if (ret == IOTC_ER_LOGIN_ALREADY_CALLED) {
/* printf("logined\n"); */
}
msleep(1000);
}
}
int Handle_IOCTRL_Cmd(struct tutk_client_info *cli, int type, char *content)
{
int ret = 0;
switch (type) {
case IOTYPE_USER_IPCAM_START:
break;
case IOTYPE_USER_IPCAM_STOP:
break;
case IOTYPE_USER_CTP_CMD_MSG:
__cmd_pro(cli, content);
break;
case IOTYPE_USER_CTP_CMD_KEEP_ALIVE:
puts("KKKKKK\n");
/* if ((ret = avSendIOCtrl(cli->cmdindex, IOTYPE_USER_CTP_CMD_KEEP_ALIVE, "CTP_KEEP_ALIVE", strlen("CTP_KEEP_ALIVE"))) < 0) { */
/* } */
break;
default:
printf("\ntype = %d content = %s\n", type, content);
break;
}
return 0;
exit:
return -1;
}
static int AuthCallBackFn(char *viewAcc, char *viewPwd)
{
if (strcmp(viewAcc, tinfo.username) == 0 && strcmp(viewPwd, tinfo.password) == 0) {
printf("\n %s suc\n", __func__);
return 1;
}
printf("\n tutk_srv.username = %s viewAcc = %s\n", tinfo.username, viewAcc);
printf("\n tutk_srv.password = %s viewPwd = %s \n", tinfo.password, viewPwd);
return 0;
}
static void thread_ForCMDServerStart(void *arg)
{
int ret;
int nResend = -1;
unsigned int ioType;
struct st_SInfo Sinfo = {0};
struct tutk_client_info *cinfo = (struct tutk_client_info *)arg;
cinfo->cmdindex = avServStart3(cinfo->session_id
, AuthCallBackFn
, 20
, 0
, CMD_CHANNEL
, &nResend);
if (cinfo->cmdindex < 0) {
goto exit;
}
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
char *ioCtrlBuf = malloc(1024);
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
if (!ioCtrlBuf) {
goto exit2;
}
while (1) {
if (cinfo->task_kill) {
goto exit2;
}
/***接收IO命令,ioType为命令号,ioCtrlBuf为参数buf,1000表示1秒超时***/
ret = avRecvIOCtrl(cinfo->cmdindex, &ioType, (char *)ioCtrlBuf, 1024, 10 * 1000);
if (ret < 0) {
if (ret == AV_ER_TIMEOUT) {
printf("tutk recv timeout\n");
os_taskq_post("tutk_state_task", 2, TUTK_CMD_TIMEOUT, (u32)cinfo);
goto exit2;
} else {
os_taskq_post("tutk_state_task", 2, TUTK_ERR, (u32)cinfo);
printf("avRecvIOCtrl ret = %d", ret);
goto exit2;
}
}
log_d("cinfo->session_id=%d\n", cinfo->session_id);
Handle_IOCTRL_Cmd(cinfo, ioType, ioCtrlBuf);
}
exit2:
if (ioCtrlBuf != NULL) {
free(ioCtrlBuf);
}
avServStop(cinfo->cmdindex);
exit:
printf("\n thread_ForCMDServerStart exit\n");
}
#if 1
/* char tmpbuf[5*1024*1024]; */
#define PCM_TYPE_AUDIO 1
#define JPEG_TYPE_VIDEO 2
#define H264_TYPE_VIDEO 3
#define PREVIEW_TYPE 4
#define DATE_TIME_TYPE 5
#define MEDIA_INFO_TYPE 6
#define PLAY_OVER_TYPE 7
#define GPS_INFO_TYPE 8
#define NO_GPS_DATA_TYPE 9
#define G729_TYPE_AUDIO 10
#define META_DATA 11
struct frm_head {
u8 type;
u8 res;
#if 0
u8 sample_seq;
#endif
u16 payload_size;
u32 seq;
u32 frm_sz;
u32 offset;
u32 timestamp;
} __attribute__((packed));
static int do_file_server_event(int fileindex, FILE_t *file_info)
{
/* struct FILE_t * file_info = (struct FILE_t *)arg; */
/* printf("fileclient start\n"); */
printf("path:%s\n", file_info->path);
printf("offset:%d\n", file_info->offset);
printf("size:%d\n", file_info->size);
/* put_buf((void *)&file_info->size, 4); */
int ret = 0;
int ret1 = 0;
struct frm_head f_head = {0};
FILE *fp = fopen(file_info->path, "r");
if (!fp) {
printf("%s open fail\n", file_info->path);
return -1;
}
if (!file_info->size) {
fclose(fp);
return 0;
}
fseek(fp, file_info->offset, SEEK_SET);
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
char *buf = malloc(file_info->size);//这内存看来申请吧,不够就小点做点处理
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
if (!buf) {
printf("malloc fail\n");
fclose(fp);
return -1;
}
ret = fread(buf, file_info->size, 1, fp);
if (ret <= 0) {
printf("read all read all \n\n");
f_head.type = PLAY_OVER_TYPE;
do {
/* printf("fileindex=%d ret=%d\n", fileindex, ret); */
memset(buf, 0xff, 32);
ret1 = avSendFrameData(fileindex, buf, 32, &f_head, sizeof(f_head));
printf("ret1=%d\n", ret1);
if (ret1 < 0) {
if (ret1 == AV_ER_EXCEED_MAX_SIZE) {
putchar('K');
os_time_dly(1);
continue;
}
log_e("\n\n\n tutk_send err ret=%d\n", ret);
fclose(fp);
free(buf);
return ret;
}
} while (ret1 != AV_ER_NoERROR);
printf("read all read all end end\n\n");
fclose(fp);
free(buf);
return -1;
}
do {
f_head.type = META_DATA;
/* printf("fileindex=%d ret=%d\n", fileindex, ret); */
ret1 = avSendFrameData(fileindex, buf, ret, &f_head, sizeof(f_head));
/* printf("ret1=%d\n", ret1); */
if (ret1 < 0) {
if (ret1 == AV_ER_EXCEED_MAX_SIZE) {
putchar('K');
os_time_dly(1);
continue;
}
log_e("\n\n\n tutk_send err ret=%d\n", ret);
fclose(fp);
free(buf);
return ret;
}
} while (ret1 != AV_ER_NoERROR);
fclose(fp);
free(buf);
/* printf("file client send end\n"); */
return 0;
}
static void thread_ForFileServerStart(void *arg)
{
int ret;
int nResend = -1;
FILE_t file_info;
unsigned int frmNo;
int outBufSize = 0;
int outFrmSize = 0;
int outFrmInfoSize = 0;
int count = 0;
char file_info_buf[1024];
int ioType = 0;
struct tutk_client_info *cinfo = (struct tutk_client_info *)arg;
//start file server channel
cinfo->fileindex = avServStart3(cinfo->session_id
, AuthCallBackFn
, 5
, 0
, FILE_CHANNEL
, &nResend);
if (cinfo->fileindex < 0) {
if (AV_ER_TIMEOUT == cinfo->fileindex) {
printf("TTTTT\n");
return ;
/* continue; */
}
printf("cinfo->fileindex=%d\n", cinfo->fileindex);
goto exit;
}
avServSetResendSize(cinfo->fileindex, 5 * 1024 * 1024);
printf("nResend=%d\n", nResend);
while (1) {
if (cinfo->task_kill) {
goto exit2;
}
ret = avRecvIOCtrl(cinfo->fileindex, &ioType, (char *)&file_info, sizeof(FILE_t), 10 * 1000);
if (ret < 0) {
if (ret == AV_ER_TIMEOUT) {
printf("tutk recv timeout\n");
continue;
}
printf("avRecvIOCtrl ret = %d", ret);
goto exit2;
}
do_file_server_event(cinfo->fileindex, &file_info);
/* avServStop(cinfo->fileindex); */
}
exit2:
avServStop(cinfo->fileindex);
exit:
/* IOTC_Session_Close(cinfo->session_id); */
printf("\n thread_ForFileServerStart exit\n");
}
#endif
static void tutk_do_listen(void *arg)
{
int ret;
int SID;
struct st_SInfo Sinfo;
while (1) {
SID = IOTC_Listen(0); //0表示不超时
if (SID < 0) {
if (SID == IOTC_ER_EXCEED_MAX_SESSION) {
os_time_dly(100);
continue;
}
printf("SID=%d\n", SID);
break;
}
if (IOTC_Session_Check(SID, &Sinfo) == IOTC_ER_NoERROR) {
char *mode[3] = {"P2P", "RLY", "LAN"};
// print session information(not a must)
// if( isdigit( Sinfo.RemoteIP[0] ))
/* printf("Client is from[IP:%s, Port:%d] Mode[%s] VPG[%d:%d:%d] VER[%X] NAT[%d] AES[%d]\n", Sinfo.RemoteIP, Sinfo.RemotePort, mode[(int)Sinfo.Mode], Sinfo.VID, Sinfo.PID, Sinfo.GID, Sinfo.IOTCVersion, Sinfo.NatType, Sinfo.isSecure); */
}
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
struct tutk_client_info *cinfo = calloc(1, sizeof(struct tutk_client_info));
printf("\n [ERROR] %s -yuyu %d\n", __FUNCTION__, __LINE__);
if (!cinfo) {
printf("tutk malloc fail\n");
IOTC_Session_Close(SID);
continue;
}
cinfo->session_id = SID;
os_mutex_pend(&tinfo.mutex, 0);
list_add_tail(&cinfo->entry, &tinfo.head);
os_mutex_post(&tinfo.mutex);
char thread_name[64];
static u32 count;
#if 1
sprintf(thread_name, "CmdServerStart_%X", count++);
printf("\n thread_name = %s \n", thread_name);
ret = thread_fork(thread_name, 28, 0x1000, 64, &cinfo->cmd_task_pid, thread_ForCMDServerStart, (void *)cinfo);
if (ret != OS_NO_ERR) {
printf("\n create %s err ,ret = %d", thread_name, ret);
}
#endif
#if 1
//文件系统子线程
sprintf(thread_name, "FileServerStart_%X", count++);
printf("\n thread_name = %s \n", thread_name);
ret = thread_fork(thread_name, 10, 0x1000, 64, &cinfo->file_task_pid, thread_ForFileServerStart, (void *)cinfo);
if (ret != OS_NO_ERR) {
printf("\n create %s err ,ret = %d", thread_name, ret);
}
#endif
}
printf("end tutk_do_listen_task \n\n");
}
void *tutk_session_cli_get(void)
{
struct tutk_client_info *cinfo = NULL;
if (list_empty(&tinfo.head)) {
return NULL;
}
cinfo = list_first_entry(&tinfo.head, struct tutk_client_info, entry);
return (void *)cinfo;
}
static int tutk_session_cli_exit(int arg)
{
struct tutk_client_info *cinfo = (struct tutk_client_info *)arg;
os_mutex_pend(&tinfo.mutex, 0);
list_del(&cinfo->entry);
os_mutex_post(&tinfo.mutex);
cinfo->task_kill = 1;
//关闭所有应用
/* video0_tutk_stop(cinfo); */
/* tutk_speak_uninit(cinfo); */
thread_kill(&cinfo->file_task_pid, KILL_WAIT);
thread_kill(&cinfo->cmd_task_pid, KILL_WAIT);
cinfo->task_kill = 0;
IOTC_Session_Close(cinfo->session_id);
free(cinfo);
return 0;
}
int tutk_noitfy_cli(void *hdl, char *msg, int msg_len)
{
struct tutk_client_info *info = (struct tutk_client_info *)hdl;
struct tutk_client_info *p = NULL;
int ret = 0;
if (!tinfo.inited) {
return -1;
}
if (info) {
if ((ret = avSendIOCtrl(info->cmdindex, IOTYPE_USER_CTP_CMD_MSG, msg, msg_len)) < 0) {
printf("start_ipcam_stream failed[%d]\n", ret);
return -1;
}
return 0;
}
os_mutex_pend(&tinfo.mutex, 0);
if (list_empty(&tinfo.head)) {
os_mutex_post(&tinfo.mutex);
return -1;
}
list_for_each_entry(p, &tinfo.head, entry) {
if ((ret = avSendIOCtrl(p->cmdindex, IOTYPE_USER_CTP_CMD_MSG, msg, msg_len)) < 0) {
printf("start_ipcam_stream failed[%d]\n", ret);
}
}
os_mutex_post(&tinfo.mutex);
return 0;
}
static void tutk_state_task(void *arg)
{
int res;
int msg[8];
while (1) {
res = os_task_pend("taskq", msg, ARRAY_SIZE(msg));
switch (res) {
case OS_TASKQ:
switch (msg[1]) {
case TUTK_CMD_TIMEOUT:
tutk_session_cli_exit(msg[2]);
break;
case TUTK_ERR:
tutk_session_cli_exit(msg[2]);
break;
case TUTK_KILL_TASK:
printf("end tutk_state_task \n\n");
return;
default:
break;
}
break;
case OS_TIMER:
break;
case OS_TIMEOUT:
break;
}
}
}
#define BIND_TOKEN "174f9d4e-b5bf-4194-8158-f00bf00ea619"
#define DEV_INFO_JSON "{\"device_uuid\":\"%s\",\"bind_token\":\"%s\"}"
static char buffer[1024];
static char *dev_info()
{
/*后面改成都VM*/
sprintf(buffer, DEV_INFO_JSON, TEST_UID, BIND_TOKEN);
return buffer;
}
static void network_ssdp_cb(u32 dest_ipaddr, enum mssdp_recv_msg_type type, char *buf, void *priv)
{
if (type == MSSDP_SEARCH_MSG) {
printf("ssdp client[0x%x] search, %s\n", dest_ipaddr, buf);
}
}
int tutk_platform_init(const char *username, const char *password)
{
int ret;
strcpy(tinfo.username, username);
strcpy(tinfo.password, password);
IOTC_Set_Max_Session_Number(MAX_CLIENT_NUMBER);
ret = IOTC_Initialize2(55556);
if (ret != IOTC_ER_NoERROR) {
printf("\n IOTC_Initialize2(), ret=[%d]\n", ret);
goto exit;
}
ret = os_mutex_create(&tinfo.mutex);
if (ret != OS_NO_ERR) {
printf("\n create list mutex err\n");
goto exit;
}
unsigned int iotcVer;
IOTC_Get_Version(&iotcVer);
int avVer = avGetAVApiVer();
unsigned char *p = (unsigned char *)&iotcVer;
unsigned char *p2 = (unsigned char *)&avVer;
char szIOTCVer[16], szAVVer[16];
sprintf(szIOTCVer, "%d.%d.%d.%d", p[3], p[2], p[1], p[0]);
sprintf(szAVVer, "%d.%d.%d.%d", p2[3], p2[2], p2[1], p2[0]);
printf("IOTCAPI version[%s] AVAPI version[%s]\n", szIOTCVer, szAVVer);
printf("UUID:%s\n", TEST_UID);
IOTC_Get_Login_Info_ByCallBackFn(tutk_login_info_cb);
avInitialize(MAX_CLIENT_NUMBER * 4);
INIT_LIST_HEAD(&tinfo.head);
ret = thread_fork("tutk_login_task", 10, 0x2000, 0, &tinfo.login_pid, tutk_login_task, NULL);
if (ret != OS_NO_ERR) {
printf("\n create thread_Login err , ret = %d \n", ret);
}
ret = thread_fork("tutk_do_listen_task", 10, 0x2000, 0, 0, tutk_do_listen, NULL);
if (ret != OS_NO_ERR) {
printf("\n create thread_listen err , ret = %d \n", ret);
}
ret = thread_fork("tutk_state_task", 25, 2048, 64, 0, tutk_state_task, NULL);
if (ret != OS_NO_ERR) {
printf("\n create tutk_state_task err , ret = %d \n", ret);
}
mssdp_init("MSSDP_SEARCH ", "MSSDP_NOTIFY ", "MSSDP_REGISTER ", 3889, network_ssdp_cb, NULL);
mssdp_set_notify_msg(dev_info(), 60);
tinfo.inited = 1;
return 0;
exit:
return -1;
}
int tutk_platform_uninit()
{
struct tutk_client_info *p = NULL;
if (!tinfo.inited) {
return 0;
}
if (!list_empty(&tinfo.head)) {
list_for_each_entry(p, &tinfo.head, entry) {
tutk_session_cli_exit((int)p);
}
}
mssdp_uninit();
IOTC_Listen_Exit();
os_taskq_post("tutk_state_task", 1, TUTK_KILL_TASK);
tinfo.kill_task = 1;
thread_kill(&tinfo.login_pid, KILL_WAIT);
tinfo.kill_task = 0;
avDeInitialize();
IOTC_DeInitialize();
os_mutex_del(&tinfo.mutex, 0);
tinfo.inited = 0;
return 0;
}
#endif