/**
    @function: int srecorder_get_crash_time(srecorder_reserved_mem_info_for_log_t *pmem_info)
    @brief: 记录死机发生的时间,顺便记录死机的原因。

    @param: pmem_info SRecorder的保留内存信息
    
    @return: 0 - 成功;-1-失败

    @note: 
*/
int srecorder_get_crash_time(srecorder_reserved_mem_info_t *pmem_info)
{
    struct timeval tv;
    /* struct timex txc; */
    struct rtc_time tm;
    int bytes_read = 0;
    char *pbuf = NULL;
    psrecorder_info_header_t pinfo_header = NULL;
        
    if (unlikely(NULL == pmem_info))
    {
        SRECORDER_PRINTK("File [%s] line [%d] invalid param or kernel symbol addr!\n", __FILE__, __LINE__);
        return -1;
    }

    if (srecorder_log_has_been_dumped(CRASH_REASON_TIME_BIT0))
    {
        SRECORDER_PRINTK("Crash reason and time have been dumped successfully!\n");
        return 0;
    }
    
    memset(&tv, 0, sizeof(struct timeval));
    /* memset(&txc, 0, sizeof(struct timex)); */
    memset(&tm, 0, sizeof(struct rtc_time));

    if (0 != srecorder_write_info_header(pmem_info, CRASH_REASON_TIME_BIT0, &pinfo_header))
    {
        return -1;
    }
    
    do_gettimeofday(&tv);
    tv.tv_sec -= sys_tz.tz_minuteswest * 60; /* 一分钟=60秒 */
    rtc_time_to_tm(tv.tv_sec, &tm);
    pbuf = pmem_info->start_addr + pmem_info->bytes_read;/* [false alarm]:there is pmem_info protect before  */
    bytes_read = SRECORDER_SNPRINTF(pmem_info->start_addr + pmem_info->bytes_read, pmem_info->bytes_left, 
        "Crash reason: %s %s Crash Time: %04d%02d%02d-%02d:%02d:%02d\n", 
        (NULL == pmem_info->crash_reason1) ? ("") : (pmem_info->crash_reason1), 
        (NULL == pmem_info->crash_reason2) ? ("") : (pmem_info->crash_reason2), 
        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 
        tm.tm_hour, tm.tm_min, tm.tm_sec);
    srecorder_renew_meminfo(pmem_info, bytes_read);
    srecorder_validate_info_header(pinfo_header, pmem_info->bytes_per_type);
    
    return 0;
}
/**
    @function: int srecorder_get_modem_log(srecorder_reserved_mem_info_for_log_t *pmem_info)
    @brief: 读取modem死机堆栈和运行日志

    @param: pmem_info SRecorder的保留内存信息
    
    @return: 0 - 成功;-1-失败

    @note: 
*/
int srecorder_get_modem_log(srecorder_reserved_mem_info_t *pmem_info)
{
    psrecorder_info_header_t pinfo_header = NULL;
    
    if (unlikely(NULL == pmem_info))
    {
        SRECORDER_PRINTK("File [%s] line [%d] invalid param or kernel symbol addr!\n", __FILE__, __LINE__);
        return -1;
    }

    if (srecorder_log_has_been_dumped(MODEM_ERR_BIT7))
    {
        SRECORDER_PRINTK("modem err has been dumped successfully!\n");
    }

    if (srecorder_log_has_been_dumped(MODEM_ERR_F3_BIT8))
    {
        SRECORDER_PRINTK("modem err f3 has been dumped successfully!\n");
    }
    
    if (pmem_info->dump_modem_crash_log_only)
    {
#if defined(CONFIG_DUMP_MODEM_LOG_BY_FIQ)
        if (pmem_info->do_delay_when_dump_modem_log)
        {
            /* do delay about 10ms */
            unsigned long ips = 0;
            
            ips = cpufreq_get_directly(smp_processor_id()) * 1000; /* KHZ = 1000*/
            if (unlikely(0x0 == ips))
            {
                ips = CONFIG_CPU_FREQ_DEFAULT_VALUE;
            }
            
            if (likely(0x0 != CONFIG_DUMP_MODEM_LOG_DELAY_MAX_MS))
            {
                srecorder_do_delay(ips / (1000 / CONFIG_DUMP_MODEM_LOG_DELAY_MAX_MS));
            }
        }
#endif

#if !defined(CONFIG_ARCH_MSM8930)
        if (!srecorder_log_has_been_dumped(MODEM_ERR_BIT7))
        {
            if (0 != srecorder_write_info_header(pmem_info, MODEM_ERR_BIT7, &pinfo_header))
            {
                return -1;
            }
            srecorder_debug_modem_err(pmem_info);
            srecorder_validate_info_header(pinfo_header, pmem_info->bytes_per_type);
        }
#else
#endif
        
#if !defined(CONFIG_ARCH_MSM8930)
        if (!srecorder_log_has_been_dumped(MODEM_ERR_F3_BIT8))
        {
            if (0 != srecorder_write_info_header(pmem_info, MODEM_ERR_F3_BIT8, &pinfo_header))
            {
                return -1;
            }
            srecorder_debug_modem_err_f3(pmem_info);
            srecorder_validate_info_header(pinfo_header, pmem_info->bytes_per_type);
        }
#else
#endif
    }
    
    return 0;
}