/*************************************************************************************** * * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. * * By downloading, copying, installing or using the software you agree to this license. * If you do not agree to this license, do not download, install, * copy or use the software. * * Copyright (C) 2014-2022, Happytimesoft Corporation, all rights reserved. * * Redistribution and use in binary forms, with or without modification, are permitted. * * 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. * ****************************************************************************************/ #include "sys_inc.h" #include "gb28181_cfg.h" #include "xml_node.h" #include "media_format.h" /***************************************************************************************/ // the default configuration file name #define GB28181_DEF_CFG "config.xml" // global gb28181 configuration variable GB28181_CFG g_gb28181_cfg; /***************************************************************************************/ void gb28181_init_config() { memset(&g_gb28181_cfg, 0, sizeof(GB28181_CFG)); g_gb28181_cfg.server_port = 5060; g_gb28181_cfg.media_protocol = 1; g_gb28181_cfg.heartbeat_interval = 60; g_gb28181_cfg.heartbeat_count = 3; g_gb28181_cfg.reg_expires = 3600; g_gb28181_cfg.media_base_port = 19000; strcpy(g_gb28181_cfg.server_ip, get_local_ip()); strcpy(g_gb28181_cfg.server_domain, g_gb28181_cfg.server_ip); strcpy(g_gb28181_cfg.device_id, "34020000001110000001"); strcpy(g_gb28181_cfg.password, "12345678"); } int gb28181_parse_video_codec(const char * buff) { if (strcasecmp(buff, "H264") == 0) { return VIDEO_CODEC_H264; } else if (strcasecmp(buff, "H265") == 0) { return VIDEO_CODEC_H265; } else if (strcasecmp(buff, "MP4") == 0) { return VIDEO_CODEC_MP4; } return VIDEO_CODEC_NONE; } int gb28181_parse_audio_codec(const char * buff) { if (strcasecmp(buff, "G711") == 0) { return AUDIO_CODEC_G711A; } else if (strcasecmp(buff, "G711A") == 0) { return AUDIO_CODEC_G711A; } else if (strcasecmp(buff, "G711U") == 0) { return AUDIO_CODEC_G711U; } else if (strcasecmp(buff, "G722") == 0) { return AUDIO_CODEC_G722; } else if (strcasecmp(buff, "AAC") == 0) { return AUDIO_CODEC_AAC; } return AUDIO_CODEC_NONE; } BOOL gb28181_parse_video(XMLN * p_node, VIDEO_INFO * p_info) { XMLN * p_codec; XMLN * p_width; XMLN * p_height; XMLN * p_framerate; XMLN * p_bitrate; p_codec = xml_node_get(p_node, "codec"); if (p_codec && p_codec->data) { p_info->codec = gb28181_parse_video_codec(p_codec->data); } p_width = xml_node_get(p_node, "width"); if (p_width && p_width->data) { p_info->width = atoi(p_width->data); if (p_info->width < 0) { p_info->width = 0; } } p_height = xml_node_get(p_node, "height"); if (p_height && p_height->data) { p_info->height = atoi(p_height->data); if (p_info->height < 0) { p_info->height = 0; } } p_framerate = xml_node_get(p_node, "framerate"); if (p_framerate && p_framerate->data) { p_info->framerate = atoi(p_framerate->data); if (p_info->framerate < 0) { p_info->framerate = 0; } } p_bitrate = xml_node_get(p_node, "bitrate"); if (p_bitrate && p_bitrate->data) { p_info->bitrate = atoi(p_bitrate->data); if (p_info->bitrate < 0) { p_info->bitrate = 0; } } return TRUE; } BOOL gb28181_parse_audio(XMLN * p_node, AUDIO_INFO * p_info) { XMLN * p_codec; XMLN * p_samplerate; XMLN * p_channels; XMLN * p_bitrate; p_codec = xml_node_get(p_node, "codec"); if (p_codec && p_codec->data) { p_info->codec = gb28181_parse_audio_codec(p_codec->data); } p_samplerate = xml_node_get(p_node, "samplerate"); if (p_samplerate && p_samplerate->data) { p_info->samplerate = atoi(p_samplerate->data); if (p_info->samplerate < 0) { p_info->samplerate = 0; } } p_channels = xml_node_get(p_node, "channels"); if (p_channels && p_channels->data) { p_info->channels = atoi(p_channels->data); if (p_info->channels < 0) { p_info->channels = 0; } else if (p_info->channels > 2) { p_info->channels = 2; } } p_bitrate = xml_node_get(p_node, "bitrate"); if (p_bitrate && p_bitrate->data) { p_info->bitrate = atoi(p_bitrate->data); if (p_info->bitrate < 0) { p_info->bitrate = 0; } } return TRUE; } BOOL gb28181_parse_output(XMLN * p_node, MEDIA_INFO * p_output) { XMLN * p_video; XMLN * p_audio; p_video = xml_node_get(p_node, "video"); if (p_video) { p_output->has_video = gb28181_parse_video(p_video, &p_output->video); } p_audio = xml_node_get(p_node, "audio"); if (p_audio) { p_output->has_audio = gb28181_parse_audio(p_audio, &p_output->audio); } return TRUE; } BOOL gb28181_parse_channel(XMLN * p_node, GBCHANNEL * p_channel) { XMLN * p_cid; XMLN * p_cname; XMLN * p_media_url; XMLN * p_output; p_cid = xml_node_get(p_node, "cid"); if (p_cid && p_cid->data) { strncpy(p_channel->cid, p_cid->data, sizeof(p_channel->cid)-1); } else { return FALSE; } p_cname = xml_node_get(p_node, "cname"); if (p_cname && p_cname->data) { strncpy(p_channel->cname, p_cname->data, sizeof(p_channel->cname)-1); } p_media_url = xml_node_get(p_node, "media_url"); if (p_media_url && p_media_url->data) { strncpy(p_channel->media_url, p_media_url->data, sizeof(p_channel->media_url)-1); } p_output = xml_node_get(p_node, "output"); if (p_output) { gb28181_parse_output(p_output, &p_channel->output); } return TRUE; } BOOL gb28181_parse_config(char * xml_buff, int rlen) { XMLN * p_node; XMLN * p_server_ip; XMLN * p_server_port; XMLN * p_server_id; XMLN * p_server_domain; XMLN * p_local_port; XMLN * p_device_id; XMLN * p_device_name; XMLN * p_password; XMLN * p_protocol; XMLN * p_media_protocol; XMLN * p_reg_expires; XMLN * p_heartbeat_interval; XMLN * p_heartbeat_count; XMLN * p_media_base_port; XMLN * p_log_enable; XMLN * p_log_level; XMLN * p_channel; p_node = xxx_hxml_parse(xml_buff, rlen); if (NULL == p_node) { return FALSE; } p_server_ip = xml_node_get(p_node, "server_ip"); if (p_server_ip && p_server_ip->data) { strncpy(g_gb28181_cfg.server_ip, p_server_ip->data, sizeof(g_gb28181_cfg.server_ip)-1); } p_server_port = xml_node_get(p_node, "server_port"); if (p_server_port && p_server_port->data) { g_gb28181_cfg.server_port = atoi(p_server_port->data); } p_server_id = xml_node_get(p_node, "server_id"); if (p_server_id && p_server_id->data) { strncpy(g_gb28181_cfg.server_id, p_server_id->data, sizeof(g_gb28181_cfg.server_id)-1); } p_server_domain = xml_node_get(p_node, "server_domain"); if (p_server_domain && p_server_domain->data) { strncpy(g_gb28181_cfg.server_domain, p_server_domain->data, sizeof(g_gb28181_cfg.server_domain)-1); } p_local_port = xml_node_get(p_node, "local_port"); if (p_local_port && p_local_port->data) { g_gb28181_cfg.local_port = atoi(p_local_port->data); } p_device_id = xml_node_get(p_node, "device_id"); if (p_device_id && p_device_id->data) { strncpy(g_gb28181_cfg.device_id, p_device_id->data, sizeof(g_gb28181_cfg.device_id)-1); } p_device_name = xml_node_get(p_node, "device_name"); if (p_device_name && p_device_name->data) { strncpy(g_gb28181_cfg.device_name, p_device_name->data, sizeof(g_gb28181_cfg.device_name)-1); } p_password = xml_node_get(p_node, "password"); if (p_password && p_password->data) { strncpy(g_gb28181_cfg.password, p_password->data, sizeof(g_gb28181_cfg.password)-1); } p_protocol = xml_node_get(p_node, "protocol"); if (p_protocol && p_protocol->data) { if (strcasecmp(p_protocol->data, "tcp") == 0) { g_gb28181_cfg.protocol = 1; } } p_media_protocol = xml_node_get(p_node, "media_protocol"); if (p_media_protocol && p_media_protocol->data) { if (strcasecmp(p_media_protocol->data, "tcp") == 0) { g_gb28181_cfg.media_protocol = 1; } } p_reg_expires = xml_node_get(p_node, "reg_expires"); if (p_reg_expires && p_reg_expires->data) { g_gb28181_cfg.reg_expires = atoi(p_reg_expires->data); } p_heartbeat_interval = xml_node_get(p_node, "heartbeat_interval"); if (p_heartbeat_interval && p_heartbeat_interval->data) { g_gb28181_cfg.heartbeat_interval = atoi(p_heartbeat_interval->data); } p_heartbeat_count = xml_node_get(p_node, "heartbeat_count"); if (p_heartbeat_count && p_heartbeat_count->data) { g_gb28181_cfg.heartbeat_count = atoi(p_heartbeat_count->data); } p_media_base_port = xml_node_get(p_node, "media_base_port"); if (p_media_base_port && p_media_base_port->data) { g_gb28181_cfg.media_base_port = atoi(p_media_base_port->data); } p_log_enable = xml_node_get(p_node, "log_enable"); if (p_log_enable && p_log_enable->data) { g_gb28181_cfg.log_enable = atoi(p_log_enable->data); } p_log_level = xml_node_get(p_node, "log_level"); if (p_log_level && p_log_level->data) { g_gb28181_cfg.log_level = atoi(p_log_level->data); } p_channel = xml_node_get(p_node, "channel"); while (p_channel && soap_strcmp(p_channel->name, "channel") == 0) { int idx = g_gb28181_cfg.channel_nums; if (gb28181_parse_channel(p_channel, &g_gb28181_cfg.channels[idx])) { g_gb28181_cfg.channel_nums++; if (g_gb28181_cfg.channel_nums >= MAX_CH_NUMS) { break; } } p_channel = p_channel->next; } xml_node_del(p_node); return TRUE; } BOOL gb28181_read_config(const char * config) { gb28181_init_config(); BOOL ret = FALSE; int len, rlen; FILE * fp = NULL; char * xml_buff = NULL; const char * filename = NULL; if (NULL == config || config[0] == '\0') { filename = GB28181_DEF_CFG; } else { filename = config; } // read config file fp = fopen(filename, "r"); if (NULL == fp) { goto FAILED; } fseek(fp, 0, SEEK_END); len = ftell(fp); if (len <= 0) { goto FAILED; } fseek(fp, 0, SEEK_SET); xml_buff = (char *) malloc(len + 1); if (NULL == xml_buff) { goto FAILED; } rlen = fread(xml_buff, 1, len, fp); if (rlen > 0) { xml_buff[rlen] = '\0'; ret = gb28181_parse_config(xml_buff, rlen); } else { log_print(HT_LOG_ERR, "%s, rlen = %d, len=%d\r\n", __FUNCTION__, rlen, len); } FAILED: if (fp) { fclose(fp); } if (xml_buff) { free(xml_buff); } return ret; } GBCHANNEL * gb28181_get_channel(const char * cid) { int i; if (strcmp(cid, g_gb28181_cfg.device_id) == 0) { return &g_gb28181_cfg.channels[0]; } for (i = 0; i < g_gb28181_cfg.channel_nums; i++) { if (strcmp(cid, g_gb28181_cfg.channels[i].cid) == 0) { return &g_gb28181_cfg.channels[i]; } } return &g_gb28181_cfg.channels[0]; }