ActivateMAT.c 10.7 KB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "./ActivateMAT.h"
#include "JZsdkLib.h"
#include "JZsdk_Base/JZsdk_Code/JZsdk_SMT_Code.h"
#include "./version_choose.h"

static T_JZsdkReturnCode ActivateMAT_create_SN_LOCK_file() ;
static T_JZsdkReturnCode ActivateMAT_delete_SN_LOCK_file() ;
static T_JZsdkReturnCode ActivateMAT_check_SN_LOCK_exists() ;
static T_JZsdkReturnCode ActivateMAT_UnLockDevice(char *data, unsigned long *deac_code);
static T_JZsdkReturnCode ActivateMAT_LockDevice(char *data, unsigned long *ac_code);
static T_JZsdkReturnCode ActivateMAT_ActivateAndUnActivate(int flag, unsigned char *SerialNumber,unsigned char *ActivationCode);



#define SN_LOCL_FILE_PATH "/root/SN_LOCK"
#define CRC32_POLYNOMIAL_UNLOCK 0xEDB88320L         //激活解锁
#define CRC32_POLYNOMIAL_LOCK   0xEDB88321L         //反激活锁住

/**********************************
 * 
 *  判断是否需要激活/反激活,且进行激活或者反激活
 *  输入 激活状态 序列号  激活码 激活码长度
 *  失败 返回JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE
 *  有进行了激活或者 反激活 则返回JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS
 * *******************************/
T_JZsdkReturnCode ActivateMAT_ActivateInterface(int SN_status, unsigned char *SerialNumber ,unsigned char *data, int data_length)
{
    T_JZsdkReturnCode ret;

    //如果数组指针为空,直接退出
    if (data == NULL)
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    
    //如果已经激活了
    if (SN_status == SNM_HAVE_ACTIVATED)
    {
        //判断是否是要反激活的
        if (data[0] == '#' && data[1] == '#')
        {
            //复合反激活的格式 指 ##+8位数
            if (data_length == 10)
            {
                ret = ActivateMAT_ActivateAndUnActivate(1, SerialNumber, data+2);
                if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
                {
                    printf("反激活失败");
                    return ret;
                }
            }
            else
            {
                printf("试图输入##反激活,但是长度为%d\n", data_length);
                return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
            }
            
        }
        else
        {
            return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
        }

    }
    //如果是未激活
    else if(SN_status == SNM_NOT_ACTIVATED)
    {
        //判断是否是要激活的
        if (data_length >= 7 )
        {
            ret = ActivateMAT_ActivateAndUnActivate(0, SerialNumber, data);
            if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
            {
                return ret;
            }
        }
        else
        {
            JZSDK_LOG_ERROR("输入的并非是激活码,或者是激活码长度不对");
            return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
        }
    }
    //既不是激活也不是反激活
    else
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/******************
 *
 *  激活与反激活
 *  flag 0为激活  flag 1为反激活
 * ******************/
static T_JZsdkReturnCode ActivateMAT_ActivateAndUnActivate(int flag, unsigned char *SerialNumber,unsigned char *ActivationCode)
{
    unsigned long Inputput_crc_code; //输入的字符串转换得到的校验码
    unsigned long local_crc_code; //根据本地序列号得到的校验码
    T_JZsdkReturnCode ret;

    //将输入的激活或反激活码字符串转化为 识别用的16进制校验码
    Inputput_crc_code = strtoul(ActivationCode, NULL, 16);           //将字符串转换为16进制unsigned long
    printf("输入激活码得到的校验码为:%08lX\n", Inputput_crc_code);

    //激活计算
    if (flag == 0)
    {
        //1、获取本地激活码
        ActivateMAT_UnLockDevice(SerialNumber, &local_crc_code);
        printf("计算得到的激活码:%08X\n", local_crc_code);

        //如果校验码 等于本地激活码
        if (Inputput_crc_code == local_crc_code) 
        {              
            //激活码正确                                                 
            JZSDK_LOG_INFO("激活码正确");     

            //删除锁文件                                    
            ret = ActivateMAT_delete_SN_LOCK_file();
            if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
            {
                JZSDK_LOG_ERROR("解除激活码锁失败");
                return ret;
            }
            
            //检查锁是否成功解除
            ret = ActivateMAT_check_SN_LOCK_exists(); 
            if (ret == JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)  //等于就是锁还存在
            {
                JZSDK_LOG_ERROR("解除激活码锁失败,锁仍然存在");
                return ret;
            }                                                                   
        } 
        else if ((Inputput_crc_code & 0x0FFFFFFF) == (local_crc_code & 0x0FFFFFFF)) { // 只比较后7位
            //激活码正确                                                 
            JZSDK_LOG_INFO("激活码正确");

            //删除锁文件                                    
            ret = ActivateMAT_delete_SN_LOCK_file();
            if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
            {
                JZSDK_LOG_ERROR("解除激活码锁失败");
                return ret;
            }

            //检查锁是否成功解除
            ret = ActivateMAT_check_SN_LOCK_exists();
            if (ret == JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)  //等于就是锁还存在
            {
                JZSDK_LOG_ERROR("解除激活码锁失败,锁仍然存在");
                return ret;
            }
        } 
        else
        {       
             //激活码错误
            JZSDK_LOG_ERROR("激活码错误"); 
            return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;                                          
        }
    }
    //反激活计算
    else if(flag == 1)
    {
        //1、获取本地激活码
        ActivateMAT_LockDevice(SerialNumber, &local_crc_code);
        printf("计算得到的反激活码:%08X\n", local_crc_code);

        //如果校验码 等于本地激活码
        if (Inputput_crc_code == local_crc_code) 
        {              
            //激活码正确                                                 
            printf("反激活正确\n");     
            //创建锁文件                                    
            ret = ActivateMAT_create_SN_LOCK_file();
            if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
            {
                JZSDK_LOG_ERROR("激活码锁创建失败");
                return ret;
            }
            
            //检查锁是否成功上锁
            ret = ActivateMAT_check_SN_LOCK_exists(); 
            if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)  //不等于就是锁还=不存在
            {
                JZSDK_LOG_ERROR("激活码锁创建失败,锁存在");
                return ret;
            }                                                                   
        } 
        else
        {       
            //反激活码错误
            printf("反激活码错误\n");            
            return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;                             
        }                                          
    }
    else
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/******************
 *
 *  激活状态判断,输入序列号类型,以及 序列号状态的地址
 *  返回成功或者失败
 * ******************/
 T_JZsdkReturnCode ActivateMAT_DeviceActivateStatus(int SN_Type, int *SN_status)
{
    // //如果序列号类型处于 UNDEFINED_SNM STANDARD_JZ_1_SNM
    // //都是认为默认激活
    // if (SN_Type == UNDEFINED_SNM || SN_Type == STANDARD_JZ_1_SNM)
    // {
    //     *SN_status = SNM_HAVE_ACTIVATED;
    //     return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
    // }
    
    // //如果为极至标准2类型 或者 dji环类型的序列号类型
    // //正常判断是否有激活

    //如果是串口程序,默认为已经激活
    if (APP_VERSION == APP_UART)
    {
        *SN_status = SNM_HAVE_ACTIVATED;
        return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
    }
    

    //如果sn锁文件存在
    if(ActivateMAT_check_SN_LOCK_exists() == JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
    {
        printf("检测到sn存在\n");
        *SN_status = SNM_NOT_ACTIVATED;
    }
    else
    {
        printf("检测到不sn存在\n");
        //如果没有sn锁,就是已经激活设备
        *SN_status = SNM_HAVE_ACTIVATED;
    }

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}


/**********************************
 * 
 *  创建SN_LOCK文件
 * 
 * *******************************/
// 函数名:create_SN_LOCK_file
// 参数:文件路径
static T_JZsdkReturnCode ActivateMAT_create_SN_LOCK_file() 
{
    return JZsdk_create_file(SN_LOCL_FILE_PATH);
}

/**********************************
 * 
 *  删除SN_LOCK文件
 * 
 * *******************************/
// 函数名:delete_SN_LOCK_file
// 参数:文件路径
static T_JZsdkReturnCode ActivateMAT_delete_SN_LOCK_file() 
{
    return JZsdk_delete_file(SN_LOCL_FILE_PATH);
}

/**********************************
 * 
 *  检查SN_LOCK锁定文件是否存在
 * 
 * *******************************/
static T_JZsdkReturnCode ActivateMAT_check_SN_LOCK_exists() 
{
    return JZsdk_check_file_exists(SN_LOCL_FILE_PATH);
}

/**********************************
 * 
 *  激活计算函数
 * 
 * *******************************/
static T_JZsdkReturnCode ActivateMAT_UnLockDevice(char *data, unsigned long *deac_code)
{
    unsigned long crc = 0xFFFFFFFF;
    int length = strlen(data);

    for (int i = 0; i < length; i++) 
    {
        crc ^= (unsigned long)data[i];

        for (int j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^ CRC32_POLYNOMIAL_UNLOCK;
            else
                crc >>= 1;
        }
    }

    crc ^= 0xFFFFFFFF;
    
    *deac_code = crc;

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/**********************************
 * 
 *  反激活计算函数
 * 
 * *******************************/
static T_JZsdkReturnCode ActivateMAT_LockDevice(char *data, unsigned long *ac_code)
{      
    unsigned long crc = 0xFFFFFFFF;
    int length = strlen(data);

   

    for (int i = 0; i < length; i++) 
    {
        crc ^= (unsigned long)data[i];

        for (int j = 0; j < 8; j++) {
            if (crc & 1)
                crc = (crc >> 1) ^  CRC32_POLYNOMIAL_LOCK;
            else
                crc >>= 1;
        }
    }

    crc ^= 0xFFFFFFFF;

    *ac_code = crc;

    printf("反激活 序列号%s crccode:%08X accode:%08X\n", data, crc, *ac_code);

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}