0
点赞
收藏
分享

微信扫一扫

linphone-PresenceServiceImpl文件对应的JNI层文件分析

alanwhy 2023-05-29 阅读 100


说明

今天是情人节,今天啥也不想说。

native函数

private native long newPresenceServiceImpl(String id, int status, String contact);
    private native void unref(long nativePtr);
    private native String getId(long nativePtr);
    private native int setId(long nativePtr, String id);
    private native int getBasicStatus(long nativePtr);
    private native int setBasicStatus(long nativePtr, int status);
    private native String getContact(long nativePtr);
    private native int setContact(long nativePtr, String contact);
    private native long getNbNotes(long nativePtr);
    private native Object getNthNote(long nativePtr, long idx);
    private native int addNote(long nativePtr, long notePtr);
    private native int clearNotes(long nativePtr);

具体的函数分析

native long newPresenceServiceImpl(String id, int status, String contact);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    newPresenceServiceImpl
 * Signature: (Ljava/lang/String;ILjava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_org_linphone_core_PresenceServiceImpl_newPresenceServiceImpl(JNIEnv *env, jobject jobj, jstring id, jint basic_status, jstring contact) {
    LinphonePresenceService *service;
    const char *cid = id ? env->GetStringUTFChars(id, NULL) : NULL;
    const char *ccontact = contact ? env->GetStringUTFChars(contact, NULL) : NULL;
    service = linphone_presence_service_new(cid, (LinphonePresenceBasicStatus)basic_status, ccontact);
    service = linphone_presence_service_ref(service);
    if (cid) env->ReleaseStringUTFChars(id, cid);
    if (ccontact) env->ReleaseStringUTFChars(contact, ccontact);
    return (jlong)service;
}

LinphonePresenceService

linphone/coreapi/presence.c:struct _LinphonePresenceService {

linphone/coreapi/linphonepresence.h:struct _LinphonePresenceService;

linphone/coreapi/linphonepresence.h:typedef struct _LinphonePresenceService LinphonePresenceService;

struct _LinphonePresenceService {
    void *user_data;
    int refcnt;
    char *id;
    LinphonePresenceBasicStatus status;
    char *contact;
    MSList *notes;              /**< A list of _LinphonePresenceNote structures. */
    time_t timestamp;
};

这个是第一个, 我觉得不是很像。

/**
 * Structure holding the information about a presence service.
 */
struct _LinphonePresenceService;

这个才是真的。

/**
 * Presence service type holding information about a presence service.
 */
typedef struct _LinphonePresenceService LinphonePresenceService;

原来LinphonePresenceService是这个的定义。

找来找去, 才会返现, presence.c还真是最后的实现呢。

linphone_presence_service_new

linphone/coreapi/presence.c:LinphonePresenceService * linphone_presence_service_new(const char *id, LinphonePresenceBasicStatus basic_status, const char *contact) {

linphone/coreapi/linphonepresence.h:LINPHONE_PUBLIC LinphonePresenceService * linphone_presence_service_new(const char *id, LinphonePresenceBasicStatus basic_status, const char *contact);

/*****************************************************************************
 * PRESENCE SERVICE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES           *
 ****************************************************************************/

LinphonePresenceService * linphone_presence_service_new(const char *id, LinphonePresenceBasicStatus basic_status, const char *contact) {
    LinphonePresenceService *service;
    char *service_id;
    if (id == NULL)
        service_id = generate_presence_id();
    else
        service_id = ms_strdup(id);
    service = presence_service_new(service_id, basic_status);
    linphone_presence_service_set_contact(service, contact);
    if (service_id != NULL)
        ms_free(service_id);
    return service;
}

generate_presence_id

linphone/coreapi/presence.c:static char * generate_presence_id(void) {

static char * generate_presence_id(void) {
    char id[7];
    int i;
    id[0] = presence_id_valid_start_characters[ortp_random() % (sizeof(presence_id_valid_start_characters)-1)];
    for (i = 1; i < 6; i++) {
        id[i] = presence_id_valid_characters[ortp_random() % (sizeof(presence_id_valid_characters)-1)];
    }
    id[6] = '\0';

    return ms_strdup(id);
}

presence_id_valid_start_characters

static char presence_id_valid_start_characters[] = ":_abcdefghijklmnopqrstuvwxyz";

presence_service_new

static LinphonePresenceService * presence_service_new(const char *id, LinphonePresenceBasicStatus status) {
    LinphonePresenceService *service = ms_new0(LinphonePresenceService, 1);
    service->refcnt = 1;
    if (id != NULL) {
        service->id = ms_strdup(id);
    }
    service->status = status;
    service->timestamp = time(NULL);
    return service;
}

linphone_presence_service_set_contact

int linphone_presence_service_set_contact(LinphonePresenceService *service, const char *contact) {
    if (service == NULL) return -1;
    if (service->contact != NULL)
        ms_free(service->contact);
    if (contact != NULL)
        service->contact = ms_strdup(contact);
    else
        service->contact = NULL;
    return 0;
}

linphone_presence_service_ref

LinphonePresenceService * linphone_presence_service_ref(LinphonePresenceService *service) {
    service->refcnt++;
    return service;
}

LinphonePresenceBasicStatus

linphone/coreapi/linphonepresence.h:typedef enum LinphonePresenceBasicStatus {

/** Basic status as defined in section 4.1.4 of RFC 3863 */
typedef enum LinphonePresenceBasicStatus {
    /** This value means that the associated contact element, if any, is ready to accept communication. */
    LinphonePresenceBasicStatusOpen,

    /** This value means that the associated contact element, if any, is unable to accept communication. */
    LinphonePresenceBasicStatusClosed
} LinphonePresenceBasicStatus;

这个状态其实就是一个枚举。

native void unref(long nativePtr);

JNIEXPORT void JNICALL Java_org_linphone_core_PresenceServiceImpl_unref(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    linphone_presence_service_unref(service);
}

linphone_presence_service_unref

linphone/coreapi/linphonepresence.h:LINPHONE_PUBLIC LinphonePresenceService * linphone_presence_service_unref(LinphonePresenceService *service);

linphone/coreapi/presence.c:LinphonePresenceService * linphone_presence_service_unref(LinphonePresenceService *service) {

LinphonePresenceService * linphone_presence_service_unref(LinphonePresenceService *service) {
    service->refcnt--;
    if (service->refcnt == 0) {
        presence_service_delete(service);
        return NULL;
    }
    return service;
}

presence_service_delete

static void presence_service_delete(LinphonePresenceService *service) {
    if (service->id != NULL) {
        ms_free(service->id);
    }
    if (service->contact != NULL) {
        ms_free(service->contact);
    }
    ms_list_for_each(service->notes, (MSIterateFunc)linphone_presence_note_unref);
    ms_list_free(service->notes);
    ms_free(service);
};

native String getId(long nativePtr);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    getId
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_linphone_core_PresenceServiceImpl_getId(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    char *cid = linphone_presence_service_get_id(service);
    jstring jid = cid ? env->NewStringUTF(cid) : NULL;
    if (cid) ms_free(cid);
    return jid;
}

linphone_presence_service_get_id

char * linphone_presence_service_get_id(const LinphonePresenceService *service) {
    if (service == NULL) return NULL;
    return ms_strdup(service->id);
}

native int setId(long nativePtr, String id);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    setId
 * Signature: (JLjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceServiceImpl_setId(JNIEnv *env, jobject jobj, jlong ptr, jstring id) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    const char *cid = id ? env->GetStringUTFChars(id, NULL) : NULL;
    linphone_presence_service_set_id(service, cid);
    if (cid) env->ReleaseStringUTFChars(id, cid);
    return (jint)0;
}

linphone_presence_service_set_id

int linphone_presence_service_set_id(LinphonePresenceService *service, const char *id) {
    if (service == NULL) return -1;
    if (service->id != NULL)
        ms_free(service->id);
    if (id == NULL)
        service->id = generate_presence_id();
    else
        service->id = ms_strdup(id);
    return 0;
}

native int getBasicStatus(long nativePtr);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    getBasicStatus
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceServiceImpl_getBasicStatus(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    return (jint)linphone_presence_service_get_basic_status(service);
}

linphone_presence_service_get_basic_status

LinphonePresenceBasicStatus linphone_presence_service_get_basic_status(const LinphonePresenceService *service) {
    if (service == NULL) return LinphonePresenceBasicStatusClosed;
    return service->status;
}

native int setBasicStatus(long nativePtr, int status);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    setBasicStatus
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceServiceImpl_setBasicStatus(JNIEnv *env, jobject jobj, jlong ptr, jint basic_status) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    return (jint)linphone_presence_service_set_basic_status(service, (LinphonePresenceBasicStatus)basic_status);
}

linphone_presence_service_set_basic_status

int linphone_presence_service_set_basic_status(LinphonePresenceService *service, LinphonePresenceBasicStatus basic_status) {
    if (service == NULL) return -1;
    service->status = basic_status;
    return 0;
}

native String getContact(long nativePtr);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    getContact
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_linphone_core_PresenceServiceImpl_getContact(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    char *ccontact = linphone_presence_service_get_contact(service);
    jstring jcontact = ccontact ? env->NewStringUTF(ccontact) : NULL;
    if (ccontact) ms_free(ccontact);
    return jcontact;
}

linphone_presence_service_get_contact

char * linphone_presence_service_get_contact(const LinphonePresenceService *service) {
    if (service->contact == NULL) return NULL;
    return ms_strdup(service->contact);
}

native int setContact(long nativePtr, String contact);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    setContact
 * Signature: (JLjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceServiceImpl_setContact(JNIEnv *env, jobject jobj, jlong ptr, jstring contact) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    const char *ccontact = contact ? env->GetStringUTFChars(contact, NULL) : NULL;
    linphone_presence_service_set_contact(service, ccontact);
    if (ccontact) env->ReleaseStringUTFChars(contact, ccontact);
    return (jint)0;
}

linphone_presence_service_set_contact

int linphone_presence_service_set_contact(LinphonePresenceService *service, const char *contact) {
    if (service == NULL) return -1;
    if (service->contact != NULL)
        ms_free(service->contact);
    if (contact != NULL)
        service->contact = ms_strdup(contact);
    else
        service->contact = NULL;
    return 0;
}

native long getNbNotes(long nativePtr);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    getNbNotes
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_org_linphone_core_PresenceServiceImpl_getNbNotes(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    return (jlong)linphone_presence_service_get_nb_notes(service);
}

linphone_presence_service_get_nb_notes

unsigned int linphone_presence_service_get_nb_notes(const LinphonePresenceService *service) {
    return ms_list_size(service->notes);
}

native Object getNthNote(long nativePtr, long idx);

/*
 * Class:     org_linphone_core_PresenceServiceImpl
 * Method:    getNthNote
 * Signature: (JJ)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_org_linphone_core_PresenceServiceImpl_getNthNote(JNIEnv *env, jobject jobj, jlong ptr, jlong idx) {
    LinphonePresenceService *service = (LinphonePresenceService *)ptr;
    LinphonePresenceNote *note = linphone_presence_service_get_nth_note(service, (unsigned int)idx);
    if (note == NULL) return NULL;
    RETURN_USER_DATA_OBJECT("PresenceNoteImpl", linphone_presence_note, note)
}

linphone_presence_service_get_nth_note

LinphonePresenceNote * linphone_presence_service_get_nth_note(const LinphonePresenceService *service, unsigned int idx) {
    if ((service == NULL) || (idx >= linphone_presence_service_get_nb_notes(service)))
        return NULL;

    return (LinphonePresenceNote *)ms_list_nth_data(service->notes, idx);
}

ms_list_nth_data

linphone/mediastreamer2/include/mediastreamer2/mscommon.h:MS2_PUBLIC void * ms_list_nth_data(const MSList *list, int index);

linphone/mediastreamer2/src/base/mscommon.c:void * ms_list_nth_data(const MSList *list, int index){

RETURN_USER_DATA_OBJECT

linphone/coreapi/linphonecore_jni.cc:#define RETURN_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \

#define RETURN_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \
    { \
        jclass jUserDataObjectClass; \
        jmethodID jUserDataObjectCtor; \
        jobject jUserDataObj; \
        jUserDataObj = (jobject)funcprefix ## _get_user_data(cobj); \
        if (jUserDataObj == NULL) { \
            jUserDataObjectClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/" javaclass)); \
            jUserDataObjectCtor = env->GetMethodID(jUserDataObjectClass,"<init>", "(J)V"); \
            jUserDataObj = env->NewObject(jUserDataObjectClass, jUserDataObjectCtor, (jlong)funcprefix ## _ref(cobj)); \
            jUserDataObj = env->NewGlobalRef(jUserDataObj); \
            funcprefix ## _set_user_data(cobj, jUserDataObj); \
            env->DeleteGlobalRef(jUserDataObjectClass); \
        } \
        return jUserDataObj; \
    }

native int addNote(long nativePtr, long notePtr);

/*
 * Class:     org_linphone_core_PresenceModelImpl
 * Method:    addNote
 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceModelImpl_addNote(JNIEnv *env, jobject jobj, jlong ptr, jstring description, jstring lang) {
    LinphonePresenceModel *model = (LinphonePresenceModel *)ptr;
    const char *cdescription = description ? env->GetStringUTFChars(description, NULL) : NULL;
    const char *clang = lang ? env->GetStringUTFChars(lang, NULL) : NULL;
    jint res = (jint)linphone_presence_model_add_note(model, cdescription, clang);
    if (cdescription) env->ReleaseStringUTFChars(description, cdescription);
    if (clang) env->ReleaseStringUTFChars(lang, clang);
    return res;
}

linphone_presence_model_add_note

int linphone_presence_model_add_note(LinphonePresenceModel *model, const char *note_content, const char *lang) {
    LinphonePresenceService *service;
    LinphonePresenceNote *note;

    if ((model == NULL) || (note_content == NULL))
        return -1;

    /* Will put the note in the first service. */
    service = ms_list_nth_data(model->services, 0);
    if (service == NULL) {
        /* If no service exists, create one. */
        service = presence_service_new(generate_presence_id(), LinphonePresenceBasicStatusClosed);
    }
    if (service == NULL)
        return -1;

    /* Search for an existing note in the specified language. */
    note = find_presence_note_in_list(service->notes, lang);
    if (note == NULL) {
        note = linphone_presence_note_new(note_content, lang);
    } else {
        linphone_presence_note_set_content(note, note_content);
    }
    if (note == NULL)
        return -1;

    presence_service_add_note(service, note);

    return 0;
}

LinphonePresenceModel

linphone/coreapi/presence.c:struct _LinphonePresenceModel {

linphone/coreapi/linphonepresence.h:struct _LinphonePresenceModel;

linphone/coreapi/linphonepresence.h:typedef struct _LinphonePresenceModel LinphonePresenceModel;

/**
 * Represents the presence model as defined in RFC 4479 and RFC 4480.
 * This model is not complete. For example, it does not handle devices.
 */
struct _LinphonePresenceModel {
    LinphoneAddress *presentity; /* "The model seeks to describe the presentity, identified by a presentity URI.*/
    void *user_data;
    int refcnt;
    MSList *services;   /**< A list of _LinphonePresenceService structures. Also named tuples in the RFC. */
    MSList *persons;    /**< A list of _LinphonePresencePerson structures. */
    MSList *notes;      /**< A list of _LinphonePresenceNote structures. */
};

LinphonePresenceNote

linphone/coreapi/presence.c:struct _LinphonePresenceNote {

struct _LinphonePresenceNote {
    void *user_data;
    int refcnt;
    char *lang;
    char *content;
};

presence_service_new

static LinphonePresenceService * presence_service_new(const char *id, LinphonePresenceBasicStatus status) {
    LinphonePresenceService *service = ms_new0(LinphonePresenceService, 1);
    service->refcnt = 1;
    if (id != NULL) {
        service->id = ms_strdup(id);
    }
    service->status = status;
    service->timestamp = time(NULL);
    return service;
}

find_presence_note_in_list

linphone/coreapi/presence.c:static LinphonePresenceNote * find_presence_note_in_list(MSList *list, const char *lang) {

static LinphonePresenceNote * find_presence_note_in_list(MSList *list, const char *lang) {
    int nb;
    int i;

    nb = ms_list_size(list);
    for (i = 0; i < nb; i++) {
        LinphonePresenceNote *note = (LinphonePresenceNote *)ms_list_nth_data(list, i);
        if (lang == NULL) {
            if (note->lang == NULL) {
                return note;
            }
        } else {
            if ((note->lang != NULL) && (strcmp(lang, note->lang) == 0)) {
                return note;
            }
        }
    }

    return NULL;
}

linphone_presence_note_new

/*****************************************************************************
 * PRESENCE NOTE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES              *
 ****************************************************************************/

LinphonePresenceNote * linphone_presence_note_new(const char *content, const char *lang) {
    LinphonePresenceNote *note;

    if (content == NULL) return NULL;
    note = ms_new0(LinphonePresenceNote, 1);
    note->refcnt = 1;
    note->content = ms_strdup(content);
    if (lang != NULL) {
        note->lang = ms_strdup(lang);
    }
    return note;
}

linphone_presence_note_set_content

int linphone_presence_note_set_content(LinphonePresenceNote *note, const char *content) {
    if (content == NULL) return -1;
    if (note->content != NULL) {
        ms_free(note->content);
    }
    note->content = ms_strdup(content);
    return 0;
}

native int clearNotes(long nativePtr);

/*
 * Class:     org_linphone_core_PresenceModelImpl
 * Method:    clearNotes
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_PresenceModelImpl_clearNotes(JNIEnv *env, jobject jobj, jlong ptr) {
    LinphonePresenceModel *model = (LinphonePresenceModel *)ptr;
    return (jint)linphone_presence_model_clear_notes(model);
}

linphone_presence_model_clear_notes

linphone/coreapi/presence.c:int linphone_presence_model_clear_notes(LinphonePresenceModel *model) {

linphone/coreapi/linphonepresence.h:LINPHONE_PUBLIC int linphone_presence_model_clear_notes(LinphonePresenceModel *model);

int linphone_presence_model_clear_notes(LinphonePresenceModel *model) {
    if (model == NULL)
        return -1;

    ms_list_for_each(model->persons, (MSIterateFunc)clear_presence_person_notes);
    ms_list_for_each(model->services, (MSIterateFunc)clear_presence_service_notes);
    ms_list_for_each(model->notes, (MSIterateFunc)linphone_presence_note_unref);
    ms_list_free(model->notes);
    model->notes = NULL;

    return 0;
}

ms_list_for_each

linphone/mediastreamer2/src/base/mscommon.c:void ms_list_for_each(const MSList *list, void (*func)(void *)){

linphone/mediastreamer2/include/mediastreamer2/mscommon.h:MS2_PUBLIC void ms_list_for_each(const MSList *list, MSIterateFunc iterate_func);
linphone/mediastreamer2/include/mediastreamer2/mscommon.h:MS2_PUBLIC void ms_list_for_each2(const MSList *list, MSIterate2Func iterate_func, void *user_data);
linphone/mediastreamer2/include/mediastreamer2/mscommon.h:MS2_PUBLIC void ms_list_for_each3(const MSList *list, MSIterate3Func iterate_func, void *user_data, void *factory);

void ms_list_for_each(const MSList *list, void (*func)(void *)){
    for(;list!=NULL;list=list->next){
        func(list->data);
    }
}

void ms_list_for_each2(const MSList *list, void (*func)(void *, void *y), void *user_data){
    for(;list!=NULL;list=list->next){
        func(list->data,user_data);
    }
}

void ms_list_for_each3(const MSList *list, void (*func)(void *, void *, void*), void *user_data, void* factory){
    for(;list!=NULL;list=list->next){
        func(list->data,user_data, factory);
    }
}


举报

相关推荐

0 条评论