RK3399 使用vendor_storage 读写设备sn、mac

发布时间 2024-01-03 17:24:57作者: xiaowang_lj

1.读写SN 比较简单,直接传字符串即可

extern "C"
JNIEXPORT jstring JNICALL
Java_com_serialno_ReadWriteSerialNo_read(JNIEnv *env, jclass type){

    static char sn_buf_idb[SERIALNO_BUF_LEN] = {0};
        uint32 i;
        int ret ;
        uint16 len;
        struct rk_vendor_req req;
        memset(sn_buf_idb,0,sizeof(sn_buf_idb));
        int sys_fd = open("/dev/vendor_storage",O_RDONLY,0);
        if(sys_fd < 0){
            LOGD("vendor_storage open fail\n");
            goto try_drmboot;
        }

        req.tag = VENDOR_REQ_TAG;
        req.id = VENDOR_SN_ID;
        req.len = RKNAND_SYS_STORGAE_DATA_LEN; /* max read length to read*/
        ret = ioctl(sys_fd, VENDOR_READ_IO, &req);
        close(sys_fd);
        if (DEBUG_LOG)
            //rknand_print_hex_data("vendor read:", (uint32*)req.data, req.len/4 + 3);
        /* return req->len is the real data length stored in the NV-storage */
        if(ret){
            LOGD("vendor read error\n");
            goto try_drmboot;
        }
        //get the sn length
        len = req.len;
        if(len > 30)
        {
        len =30;
        }
        if(len <= 0)
        {
        goto try_drmboot;
        }
        memcpy(sn_buf_idb,req.data,len);
        if (DEBUG_LOG)
            LOGD("vendor read sn_buf_idb:%s\n",sn_buf_idb);
        return 0;

    try_drmboot:
        LOGD("----vendor read sn error,try drmboot----");
        //rknand_sys_storage_test_sn();
        return 0;


}

extern "C"
JNIEXPORT jint JNICALL
Java_com_serialno_ReadWriteSerialNo_write(JNIEnv *env, jclass type,jstring sn){
    int fd;
    int ret = 0;
    int len = 0;
    struct rk_vendor_req req;
    struct rk_vendor_req *p_req = &req;

    jboolean iscopy;
    const char *sn_utf = env->GetStringUTFChars(sn, &iscopy);
    LOGD("write serial no = %s", sn_utf);

    fd = open("/dev/vendor_storage", O_RDWR, 0);
    LOGD("open() fd = %d", fd);

    if (fd == -1) {
        LOGE("Cannot open port");
        ret = -1;
    }

    p_req->tag = VENDOR_REQ_TAG;
    p_req->id = VENDOR_SN_ID;
    p_req->len = RKNAND_SYS_STORGAE_DATA_LEN;

    len = strlen(sn_utf);
    LOGD("p_req->len = %d", len);

    if(len > SERIALNO_BUF_LEN){
        len = SERIALNO_BUF_LEN;
    }
    memset(p_req->data, 0, RKNAND_SYS_STORGAE_DATA_LEN);
    memcpy(p_req->data, sn_utf, len);
    ret = ioctl(fd, VENDOR_WRITE_IO, p_req);
    close(fd);

    env->ReleaseStringUTFChars(sn, sn_utf);

    LOGD("vendor write sn = %s, ret = %d\n", p_req->data, ret);

    return ret;
}

2.读写MAC 相对复杂,不能直接传入字符串,读的时候需要从十六进制转成十进制 写的时候需要从十进制转成十六进制 (对于使用者比较友好)

mac地址格式为 50:af:73:44:ff:12(十六进制) 但是在vendor_storage 里是以十进制的格式存储的,占用六个字节, 比如50对应vendor_storage 里data[0] = 5*16+0 = 80 需要进行转换

//十进制转十六进制
void hexToAscii(uint8_t *hexData, size_t dataSize, char *asciiBuffer) {

    for (size_t i = 0; i < dataSize; ++i) {
        sprintf(&asciiBuffer[i * 2], "%02X", hexData[i]);
    }
}
//十六进制转十进制
int getNum(char arr[]){
    int m=0;
    int sz=2;
    LOGD("sz = %d", sz);
    int i=0;
    for(i=0;i<sz;i++)
    {
        if(arr[i]>='0'&&arr[i]<='9'){
            m=m*16+arr[i]-'0';
        }
        else
        {
            m=m*16+arr[i]-'A'+10;
        }
    }
    LOGD("m = %d", m);
    return m;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_serialno_ReadWriteSerialNo_read(JNIEnv *env, jclass type,jint id){
    int fd;
    int ret = 0;
    int len = 0;
    char r_buf[RKNAND_SYS_STORGAE_DATA_LEN]={0};
    uint8 error[]="error";
    struct rk_vendor_req req;
    struct rk_vendor_req *p_req = &req;

    p_req->tag = VENDOR_REQ_TAG;
    if(id == 1)
        p_req->id = VENDOR_SN_ID;
    else if(id == 3)  p_req->id = VENDOR_LAN_MAC_ID;
    p_req->len = RKNAND_SYS_STORGAE_DATA_LEN;
    fd = open("/dev/vendor_storage", O_RDWR, 0);
    LOGD("open() fd = %d", fd);

    if (fd == -1) {
        LOGE("Cannot open port");
        ret = -1;
    }else{
        ret = ioctl(fd, VENDOR_READ_IO, p_req);
        close(fd);
    }

    if (!ret) {
        if(id == 1)
            len =  strlen((char*)p_req->data);
        else if(id == 3)
            len =  strlen((char*)p_req->data)*2;
        if(len <= 0){
            len = strlen((char*)error);
            memcpy(r_buf, error, len);
        }else{
        //sprintf(r_buf, "%d", p_req->data[0]);
         if(id == 1)
            memcpy(r_buf, p_req->data,len);
         else if(id == 3)
            hexToAscii(p_req->data,len,r_buf);
            //memcpy(r_buf, p_req->data,len);

            //sprintf(r_buf, "%s", r_buf);
            //LOGD("vendor read sn1 = %c  len = %c, \n",(char)p_req->data[0], (char)p_req->data[1]);
            //LOGD("vendor read sn1 = %s  len = %d, \n",r_buf, len);
        }
    }else{
        len = strlen((char*)error);
        memcpy(r_buf, error, len);
    }
    //convert(r_buf);

    LOGD("vendor read sn2 = %s  len = %d, \n", r_buf, len);

    jclass strClass = (env)->FindClass("java/lang/String");
    jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    jbyteArray bytes = (env)->NewByteArray(len);
    (env)->SetByteArrayRegion(bytes, 0, len, (jbyte*) r_buf);
    jstring encoding = (env)->NewStringUTF("utf-8");
    return (jstring) (env)->NewObject(strClass, ctorID, bytes,encoding);



}

extern "C"
JNIEXPORT jint JNICALL
Java_com_serialno_ReadWriteSerialNo_write(JNIEnv *env, jclass type,jint id,jstring sn){
    int fd;
    int ret = 0;
    int len = 0;
    struct rk_vendor_req req;
    struct rk_vendor_req *p_req = &req;

    jboolean iscopy;
    const char *sn_utf = env->GetStringUTFChars(sn, &iscopy);
    LOGD("write serial no = %s", sn_utf);

    fd = open("/dev/vendor_storage", O_RDWR, 0);
    LOGD("open() fd = %d", fd);

    if (fd == -1) {
        LOGE("Cannot open port");
        ret = -1;
    }

    p_req->tag = VENDOR_REQ_TAG;
    //p_req->id = VENDOR_SN_ID;
    if(id == 1)
       p_req->id = VENDOR_SN_ID;
    else if(id == 3)  p_req->id = VENDOR_LAN_MAC_ID;
    p_req->len = RKNAND_SYS_STORGAE_DATA_LEN;

    len = strlen(sn_utf);
    LOGD("p_req->len = %d", len);

    if(len > SERIALNO_BUF_LEN){
        len = SERIALNO_BUF_LEN;
    }
    if(id == 3){
        int k=0;
        for(int i=0;i<len-1;i+=2){
            char num[2] = {sn_utf[i],sn_utf[i+1]};
            p_req->data[k++] = getNum(num);
        }
    }else if(id == 1){
        memset(p_req->data, 0, RKNAND_SYS_STORGAE_DATA_LEN);
        memcpy(p_req->data, sn_utf, len);
    }

    ret = ioctl(fd, VENDOR_WRITE_IO, p_req);
    close(fd);

    env->ReleaseStringUTFChars(sn, sn_utf);

    LOGD("vendor write sn = %s, ret = %d\n", p_req->data, ret);

    return ret;
}