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

说明

native函数

    private native String getEventName(long nativeptr);
    private native int acceptSubscription(long nativeptr);
    private native int denySubscription(long nativeptr, int reason);
    private native int notify(long nativeptr, String type, String subtype, byte data[], String encoding);
    private native int updateSubscribe(long nativePtr, String type, String subtype, byte data[], String encoding);
    private native int updatePublish(long nativePtr, String type, String subtype, byte data[], String encoding);
    private native int terminate(long nativePtr);
    private native int getReason(long nativePtr);
    private native int getSubscriptionDir(long nativeptr);
    private native int getSubscriptionState(long nativeptr);
    private native void unref(long nativeptr);
    private native void addCustomHeader(long ptr, String name, String value);
    private native String getCustomHeader(long ptr, String name);
    private native void sendSubscribe(long ptr, String type, String subtype, byte data [], String encoding);
    private native void sendPublish(long ptr, String type, String subtype, byte data [], String encoding);
    private native long getErrorInfo(long nativePtr);
    private native Object getCore(long nativePtr);

具体的函数分析

getEventName

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    getEventName
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneEventImpl_getEventName(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    const char *evname=linphone_event_get_name(ev);
    return evname ? env->NewStringUTF(evname) : NULL;
}

linphone_event_get_name

const char *linphone_event_get_name(const LinphoneEvent *lev){
    return lev->name;
}

LinphoneEvent

/**
 * @addtogroup event_api
 * @{
**/

struct _LinphoneEvent;

/**
 * Object representing an event state, which is subcribed or published.
 * @see linphone_core_publish()
 * @see linphone_core_subscribe()
**/
typedef struct _LinphoneEvent LinphoneEvent;

在private.h中有_LinphoneEvent的定义

struct _LinphoneEvent{
    belle_sip_object_t base;
    LinphoneSubscriptionDir dir;
    LinphoneCore *lc;
    SalOp *op;
    SalCustomHeader *send_custom_headers;
    LinphoneSubscriptionState subscription_state;
    LinphonePublishState publish_state;
    void *userdata;
    char *name;
    int expires;
    bool_t terminating;
    bool_t is_out_of_dialog_op; /*used for out of dialog notify*/
    bool_t internal;
};

LinphoneSubscriptionDir

submodules/linphone/coreapi/event.h:enum _LinphoneSubscriptionDir{
submodules/linphone/coreapi/event.h: * Typedef alias for _LinphoneSubscriptionDir
submodules/linphone/coreapi/event.h:typedef enum _LinphoneSubscriptionDir LinphoneSubscriptionDir;
/**
 * Enum for subscription direction (incoming or outgoing).
**/
enum _LinphoneSubscriptionDir{
    LinphoneSubscriptionIncoming, /**< Incoming subscription. */
    LinphoneSubscriptionOutgoing, /**< Outgoing subscription. */
    LinphoneSubscriptionInvalidDir /**< Invalid subscription direction. */
};

SalCustomHeader

submodules/linphone/include/sal/sal.h:struct SalCustomHeader;
submodules/linphone/include/sal/sal.h:typedef struct SalCustomHeader SalCustomHeader;

LinphoneCore

submodules/linphone/coreapi/linphonecore.h:struct _LinphoneCore;
submodules/linphone/coreapi/linphonecore.h:typedef struct _LinphoneCore LinphoneCore;

SalOp

submodules/linphone/include/sal/sal.h:struct SalOp;
submodules/linphone/include/sal/sal.h:typedef struct SalOp SalOp;
submodules/linphone/include/sal/sal.h:typedef struct SalOpBase{
submodules/linphone/coreapi/bellesip_sal/sal_impl.h:struct SalOp{
struct SalOp{
    SalOpBase base;
    const belle_sip_listener_callbacks_t *callbacks;
    SalErrorInfo error_info;
    belle_sip_client_transaction_t *pending_auth_transaction;
    belle_sip_server_transaction_t* pending_server_trans;
    belle_sip_server_transaction_t* pending_update_server_trans;
    belle_sip_client_transaction_t* pending_client_trans;
    SalAuthInfo* auth_info;
    belle_sip_dialog_t* dialog;
    belle_sip_header_replaces_t *replaces;
    belle_sip_header_referred_by_t *referred_by;
    SalMediaDescription *result;
    belle_sdp_session_description_t *sdp_answer;
    SalOpState state;
    SalOpDir dir;
    belle_sip_refresher_t* refresher;
    int ref;
    SalOpType type;
    SalPrivacyMask privacy;
    belle_sip_header_t *event; /*used by SalOpSubscribe kinds*/
    SalOpSDPHandling sdp_handling;
    int auth_requests; /*number of auth requested for this op*/
    bool_t cnx_ip_to_0000_if_sendonly_enabled;
    bool_t auto_answer_asked;
    bool_t sdp_offering;
    bool_t call_released;
    bool_t manual_refresher;
    bool_t has_auth_pending;
    bool_t supports_session_timers;
    bool_t op_released;
};

SalOpBase

*this structure must be at the first byte of the SalOp structure defined by implementors*/
typedef struct SalOpBase{
    Sal *root;
    char *route; /*or request-uri for REGISTER*/
    MSList* route_addresses; /*list of SalAddress* */
    SalAddress* contact_address;
    char *from;
    SalAddress* from_address;
    char *to;
    SalAddress* to_address;
    char *origin;
    SalAddress* origin_address;
    char *remote_ua;
    SalAddress* remote_contact_address;
    char *remote_contact;
    SalMediaDescription *local_media;
    SalMediaDescription *remote_media;
    void *user_pointer;
    const char* call_id;
    char* realm;
    SalAddress* service_route; /*as defined by rfc3608, might be a list*/
    SalCustomHeader *sent_custom_headers;
    SalCustomHeader *recv_custom_headers;
    char* entity_tag; /*as defined by rfc3903 (I.E publih)*/
} SalOpBase;

SalErrorInfo

typedef struct SalErrorInfo{
    SalReason reason;
    char *status_string;
    int protocol_code;
    char *warnings;
    char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;

belle_sip_client_transaction_t

submodules/belle-sip/include/belle-sip/types.h:typedef struct belle_sip_client_transaction belle_sip_client_transaction_t;
struct belle_sip_client_transaction{
    belle_sip_transaction_t base;
    belle_sip_uri_t* preset_route; /*use to store outbound proxy, will be helpful for refresher*/
    belle_sip_hop_t* next_hop; /*use to send cancel request*/
};

belle_sip_server_transaction_t

struct belle_sip_client_transaction{
    belle_sip_transaction_t base;
    belle_sip_uri_t* preset_route; /*use to store outbound proxy, will be helpful for refresher*/
    belle_sip_hop_t* next_hop; /*use to send cancel request*/
};

就是这个结构体的typedef定义。

SalAuthInfo

submodules/linphone/include/sal/sal.h:typedef struct SalAuthInfo{

typedef struct SalAuthInfo{
    char *username;
    char *userid;
    char *password;
    char *realm;
    char *domain;
    char *ha1;
    SalAuthMode mode;
    SalSigningKey *key;
    SalCertificatesChain *certificates;
}SalAuthInfo;

belle_sip_dialog_t

belle_sip_header_replaces_t

submodules/belle-sip/include/belle-sip/headers.h:typedef struct _belle_sip_header_replaces belle_sip_header_replaces_t;

belle_sip_header_referred_by_t

submodules/belle-sip/include/belle-sip/headers.h:  typedef struct _belle_sip_header_referred_by belle_sip_header_referred_by_t;

SalMediaDescription

submodules/linphone/include/sal/sal.h:typedef struct SalMediaDescription{
typedef struct SalMediaDescription{
    int refcount;
    char name[64];
    char addr[64];
    char username[64];
    int nb_streams;
    int bandwidth;
    unsigned int session_ver;
    unsigned int session_id;
    SalStreamDir dir;
    SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
    SalCustomSdpAttribute *custom_sdp_attributes;
    OrtpRtcpXrConfiguration rtcp_xr;
    char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN];
    char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN];
    bool_t ice_lite;
    bool_t set_nortpproxy;
    bool_t pad[2];
} SalMediaDescription;

belle_sdp_session_description_t

submodules/belle-sip/include/belle-sip/belle-sdp.h:typedef struct _belle_sdp_session_description belle_sdp_session_description_t;
submodules/belle-sip/src/belle_sdp_impl.c:struct _belle_sdp_session_description {
/************************
 * session_description
 ***********************/
struct _belle_sdp_session_description {
    belle_sdp_base_description_t base_description;
    belle_sdp_version_t* version;
    belle_sip_list_t* emails;
    belle_sdp_origin_t* origin;
    belle_sdp_session_name_t* session_name;
    belle_sip_list_t* phones;
    belle_sip_list_t* times;
    belle_sdp_uri_t* uri;
    belle_sdp_uri_t* zone_adjustments;
    belle_sip_list_t* media_descriptions;

 };

SalOpState

submodules/linphone/coreapi/bellesip_sal/sal_impl.h:typedef enum SalOpState {
typedef enum SalOpState {
    SalOpStateEarly=0
    ,SalOpStateActive
    ,SalOpStateTerminating /*this state is used to wait until a proceeding state, so we can send the cancel*/
    ,SalOpStateTerminated
}SalOpState;

LinphoneSubscriptionState

submodules/linphone/coreapi/event.h:enum _LinphoneSubscriptionState{
/**
 * Enum for subscription states.
**/
enum _LinphoneSubscriptionState{
    LinphoneSubscriptionNone, /**< Initial state, should not be used.**/
    LinphoneSubscriptionOutgoingProgress, /**<An outgoing subcription was sent*/
    LinphoneSubscriptionIncomingReceived, /**<An incoming subcription is received*/
    LinphoneSubscriptionPending, /**<Subscription is pending, waiting for user approval*/
    LinphoneSubscriptionActive, /**<Subscription is accepted.*/
    LinphoneSubscriptionTerminated, /**<Subscription is terminated normally*/
    LinphoneSubscriptionError, /**<Subscription encountered an error, indicated by linphone_event_get_reason()*/
    LinphoneSubscriptionExpiring, /**<Subscription is about to expire, only sent if [sip]->refresh_generic_subscribe property is set to 0.*/
};

LinphonePublishState

submodules/linphone/coreapi/event.h:enum _LinphonePublishState{
/**
 * Enum for publish states.
**/
enum _LinphonePublishState{
    LinphonePublishNone, /**< Initial state, do not use**/
    LinphonePublishProgress, /**<An outgoing publish was created and submitted*/
    LinphonePublishOk, /**<Publish is accepted.*/
    LinphonePublishError, /**<Publish encoutered an error, linphone_event_get_reason() gives reason code*/
    LinphonePublishExpiring, /**<Publish is about to expire, only sent if [sip]->refresh_generic_publish property is set to 0.*/
    LinphonePublishCleared /**<Event has been un published*/
};

SalOpDir

submodules/linphone/coreapi/bellesip_sal/sal_impl.h:typedef enum SalOpDir {
typedef enum SalOpDir {
    SalOpDirIncoming=0
    ,SalOpDirOutgoing
}SalOpDir;

belle_sip_refresher_t

SalOpType

submodules/linphone/coreapi/bellesip_sal/sal_impl.h:typedef enum SalOpType {
typedef enum SalOpType {
    SalOpUnknown,
    SalOpRegister,
    SalOpCall,
    SalOpMessage,
    SalOpPresence,
    SalOpPublish,
    SalOpSubscribe
}SalOpType;

SalPrivacyMask

submodules/linphone/include/sal/sal.h:typedef  unsigned int SalPrivacyMask;

belle_sip_header_t

SalOpSDPHandling

submodules/linphone/include/sal/sal.h:} SalOpSDPHandling;
typedef enum {
    SalOpSDPNormal = 0, /** No special handling for SDP */
    SalOpSDPSimulateError, /** Will simulate an SDP parsing error */
    SalOpSDPSimulateRemove /** Will simulate no SDP in the op */
} SalOpSDPHandling;

acceptSubscription

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    acceptSubscription
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_acceptSubscription(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return linphone_event_accept_subscription(ev);
}

linphone_event_accept_subscription

submodules/linphone/coreapi/event.h:LINPHONE_PUBLIC int linphone_event_accept_subscription(LinphoneEvent *lev);
submodules/linphone/coreapi/event.c:int linphone_event_accept_subscription(LinphoneEvent *lev){
int linphone_event_accept_subscription(LinphoneEvent *lev){
    int err;
    if (lev->subscription_state!=LinphoneSubscriptionIncomingReceived){
        ms_error("linphone_event_accept_subscription(): cannot accept subscription if subscription wasn't just received.");
        return -1;
    }
    err=sal_subscribe_accept(lev->op);
    if (err==0){
        linphone_event_set_state(lev,LinphoneSubscriptionActive);
    }
    return err;
}

sal_subscribe_accept

submodules/linphone/include/sal/sal.h:int sal_subscribe_accept(SalOp *op);
submodules/linphone/coreapi/bellesip_sal/sal_op_events.c:int sal_subscribe_accept(SalOp *op){
int sal_subscribe_accept(SalOp *op){
    belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans));
    belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
    belle_sip_response_t* resp = sal_op_create_response_from_request(op,req,200);
    belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires));
    belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
    return 0;
}

linphone_event_set_state

submodules/linphone/coreapi/private.h:void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state);
submodules/linphone/coreapi/event.c:void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
    if (lev->subscription_state!=state){
        ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state));
        lev->subscription_state=state;
        linphone_core_notify_subscription_state_changed(lev->lc,lev,state);
        if (state==LinphoneSubscriptionTerminated){
            linphone_event_unref(lev);
        }
    }
}

linphone_core_notify_subscription_state_changed

submodules/linphone/coreapi/private.h:void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state);
submodules/linphone/coreapi/event.c:        linphone_core_notify_subscription_state_changed(lev->lc,lev,state);

denySubscription

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    denySubscription
 * Signature: (JI)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_denySubscription(JNIEnv *env, jobject jobj, jlong evptr, int reason){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return linphone_event_deny_subscription(ev,(LinphoneReason)reason);
}

linphone_event_deny_subscription

int linphone_event_deny_subscription(LinphoneEvent *lev, LinphoneReason reason){
    int err;
    if (lev->subscription_state!=LinphoneSubscriptionIncomingReceived){
        ms_error("linphone_event_deny_subscription(): cannot deny subscription if subscription wasn't just received.");
        return -1;
    }
    err=sal_subscribe_decline(lev->op,linphone_reason_to_sal(reason));
    linphone_event_set_state(lev,LinphoneSubscriptionTerminated);
    return err;
}

sal_subscribe_decline

submodules/linphone/include/sal/sal.h:int sal_subscribe_decline(SalOp *op, SalReason reason);
submodules/linphone/coreapi/bellesip_sal/sal_op_events.c:int sal_subscribe_decline(SalOp *op, SalReason reason){
submodules/linphone/coreapi/presence.c:             sal_subscribe_decline(op,SalReasonDeclined);
submodules/linphone/coreapi/event.c:    err=sal_subscribe_decline(lev->op,linphone_reason_to_sal(reason));
int sal_subscribe_decline(SalOp *op, SalReason reason){
    belle_sip_response_t*  resp = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),
                                       sal_reason_to_sip_code(reason));
    belle_sip_server_transaction_send_response(op->pending_server_trans,resp);
    return 0;
}

belle_sip_response_create_from_request

submodules/belle-sip/include/belle-sip/message.h:BELLESIP_EXPORT belle_sip_response_t *belle_sip_response_create_from_request(belle_sip_request_t *req, int status_code);
submodules/belle-sip/src/message.c:belle_sip_response_t *belle_sip_response_create_from_request(belle_sip_request_t *req, int status_code){
/*
 * note: we must not assume the request to be well formed because this function may be used to generate 400 Bad request response.
 */
belle_sip_response_t *belle_sip_response_create_from_request(belle_sip_request_t *req, int status_code){
    belle_sip_response_t *resp=belle_sip_response_new();
    belle_sip_header_t *h;
    belle_sip_header_to_t *to;
    const belle_sip_list_t *vias;

    belle_sip_response_init_default(resp,status_code,NULL);
    if (status_code==100 && (h=belle_sip_message_get_header((belle_sip_message_t*)req,"timestamp"))){
        belle_sip_message_add_header((belle_sip_message_t*)resp,h);
    }
    vias=belle_sip_message_get_headers ((belle_sip_message_t*)req,"via");
    belle_sip_message_add_headers((belle_sip_message_t*)resp,vias);
    h=belle_sip_message_get_header((belle_sip_message_t*)req,"from");
    if (h) belle_sip_message_add_header((belle_sip_message_t*)resp,h);
    h=belle_sip_message_get_header((belle_sip_message_t*)req,"to");
    if (h){
        if (status_code!=100){
            //so that to tag can be added
            to=(belle_sip_header_to_t*)belle_sip_object_clone((belle_sip_object_t*)h);
        }else{
            to=(belle_sip_header_to_t*)h;
        }
        belle_sip_message_add_header((belle_sip_message_t*)resp,(belle_sip_header_t*)to);
    }
    h=belle_sip_message_get_header((belle_sip_message_t*)req,"call-id");
    if (h) belle_sip_message_add_header((belle_sip_message_t*)resp,h);
    h=belle_sip_message_get_header((belle_sip_message_t*)req,"cseq");
    if (h){
        belle_sip_message_add_header((belle_sip_message_t*)resp,h);
    }
    return resp;
}

belle_sip_server_transaction_send_response

void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
    if (lev->subscription_state!=state){
        ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state));
        lev->subscription_state=state;
        linphone_core_notify_subscription_state_changed(lev->lc,lev,state);
        if (state==LinphoneSubscriptionTerminated){
            linphone_event_unref(lev);
        }
    }
}

linphone_event_set_state

submodules/linphone/coreapi/event.c:void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
    if (lev->subscription_state!=state){
        ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state));
        lev->subscription_state=state;
        linphone_core_notify_subscription_state_changed(lev->lc,lev,state);
        if (state==LinphoneSubscriptionTerminated){
            linphone_event_unref(lev);
        }
    }
}

notify

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    notify
 * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){
    LinphoneContent * content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent *)evptr),
                        jtype, jsubtype, jdata, jencoding, NULL);
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    jint err;

    err=linphone_event_notify(ev, content);

    if (content){
        linphone_content_unref(content);
    }
    return err;
}

create_content_from_java_args

submodules/linphone/coreapi/linphonecore_jni.cc:static LinphoneContent *create_content_from_java_args(JNIEnv *env, LinphoneCore *lc, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding, jstring jname){
static LinphoneContent *create_content_from_java_args(JNIEnv *env, LinphoneCore *lc, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding, jstring jname){
    LinphoneContent *content = NULL;
    if (jtype){
        content = linphone_core_create_content(lc);
        void *data = (void*)env->GetByteArrayElements(jdata,NULL);
        const char *tmp;

        linphone_content_set_type(content, tmp = env->GetStringUTFChars(jtype, NULL));
        env->ReleaseStringUTFChars(jtype, tmp);

        linphone_content_set_subtype(content, tmp = env->GetStringUTFChars(jsubtype, NULL));
        env->ReleaseStringUTFChars(jsubtype, tmp);

        if (jname){
            linphone_content_set_name(content, tmp = env->GetStringUTFChars(jname, NULL));
            env->ReleaseStringUTFChars(jname, tmp);
        }

        if (jencoding){
            linphone_content_set_encoding(content, tmp = env->GetStringUTFChars(jencoding,NULL));
            env->ReleaseStringUTFChars(jencoding, tmp);
        }

        linphone_content_set_buffer(content, data, env->GetArrayLength(jdata));
        env->ReleaseByteArrayElements(jdata,(jbyte*)data,JNI_ABORT);
    }
    return content;
}

linphone_content_set_type

submodules/linphone/coreapi/content.h:LINPHONE_PUBLIC void linphone_content_set_type(LinphoneContent *content, const char *type);

submodules/linphone/coreapi/content.c:void linphone_content_set_type(LinphoneContent *content, const char *type) {
void linphone_content_set_type(LinphoneContent *content, const char *type) {
    sal_body_handler_set_type(content->body_handler, type);
}

sal_body_handler_set_type

submodules/linphone/coreapi/sal.c:void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type) {
void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type) {
    belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
    if (content_type == NULL) {
        content_type = belle_sip_header_content_type_new();
        belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), BELLE_SIP_HEADER(content_type));
    }
    belle_sip_header_content_type_set_type(content_type, type);
}

linphone_content_set_name

submodules/linphone/coreapi/content.h:LINPHONE_PUBLIC void linphone_content_set_name(LinphoneContent *content, const char *name);

submodules/linphone/coreapi/content.c:void linphone_content_set_name(LinphoneContent *content, const char *name) {
void linphone_content_set_name(LinphoneContent *content, const char *name) {
    if (content->name != NULL) {
        belle_sip_free(content->name);
        content->name = NULL;
    }
    if (name != NULL) {
        content->name = belle_sip_strdup(name);
    }
}

linphone_content_set_encoding

submodules/linphone/coreapi/content.h:LINPHONE_PUBLIC void linphone_content_set_encoding(LinphoneContent *content, const char *encoding);
submodules/linphone/coreapi/content.c:void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) {
    sal_body_handler_set_encoding(content->body_handler, encoding);
}

sal_body_handler_set_encoding

submodules/linphone/include/sal/sal.h:void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding);
submodules/linphone/coreapi/sal.c:void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding) {
void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding) {
    belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding");
    if (content_encoding != NULL) {
        belle_sip_body_handler_remove_header_from_ptr(BELLE_SIP_BODY_HANDLER(body_handler), content_encoding);
    }
    belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), belle_sip_header_create("Content-Encoding", encoding));
}

linphone_content_set_buffer

void linphone_content_set_buffer(LinphoneContent *content, const void *buffer, size_t size) {
    void *data;
    sal_body_handler_set_size(content->body_handler, size);
    data = belle_sip_malloc(size + 1);
    memcpy(data, buffer, size);
    ((char *)data)[size] = '\0';
    sal_body_handler_set_data(content->body_handler, data);
}

sal_body_handler_set_size

submodules/linphone/include/sal/sal.h:void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size);
submodules/linphone/coreapi/sal.c:void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size) {
void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size) {
    belle_sip_header_content_length_t *content_length = BELLE_SIP_HEADER_CONTENT_LENGTH(sal_body_handler_find_header(body_handler, "Content-Length"));
    if (content_length == NULL) {
        content_length = belle_sip_header_content_length_new();
        belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), BELLE_SIP_HEADER(content_length));
    }
    belle_sip_header_content_length_set_content_length(content_length, size);
    belle_sip_body_handler_set_size(BELLE_SIP_BODY_HANDLER(body_handler), size);
}

sal_body_handler_set_data

void sal_body_handler_set_data(SalBodyHandler *body_handler, void *data) {
    belle_sip_memory_body_handler_set_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(body_handler), data);
}

belle_sip_memory_body_handler_set_buffer

submodules/belle-sip/include/belle-sip/bodyhandler.h:BELLESIP_EXPORT void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *obj, void *buffer);
submodules/belle-sip/src/bodyhandler.c:void belle_sip_memory_body_handler_set_buffer(belle_sip_memory_body_handler_t *obj, void *buffer) {

linphone_event_notify

int linphone_event_notify(LinphoneEvent *lev, const LinphoneContent *body){
    SalBodyHandler *body_handler;
    if (lev->subscription_state!=LinphoneSubscriptionActive){
        ms_error("linphone_event_notify(): cannot notify if subscription is not active.");
        return -1;
    }
    if (lev->dir!=LinphoneSubscriptionIncoming){
        ms_error("linphone_event_notify(): cannot notify if not an incoming subscription.");
        return -1;
    }
    body_handler = sal_body_handler_from_content(body);
    return sal_notify(lev->op, body_handler);
}

linphone_content_unref

submodules/linphone/coreapi/content.h:LINPHONE_PUBLIC void linphone_content_unref(LinphoneContent *content);

submodules/linphone/coreapi/content.c:void linphone_content_unref(LinphoneContent *content) {
void linphone_content_unref(LinphoneContent *content) {
    belle_sip_object_unref(content);
}

updateSubscribe

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    updateSubscribe
 * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){
    LinphoneContent * content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent *)evptr),
                        jtype, jsubtype, jdata, jencoding, NULL);
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    jint err;

    err=linphone_event_update_subscribe(ev, content);

    if (content) linphone_content_unref(content);
    return err;
}

linphone_event_update_subscribe

int linphone_event_update_subscribe(LinphoneEvent *lev, const LinphoneContent *body){
    return linphone_event_send_subscribe(lev,body);
}
int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *body){
    SalBodyHandler *body_handler;
    int err;

    if (lev->dir!=LinphoneSubscriptionOutgoing){
        ms_error("linphone_event_send_subscribe(): cannot send or update something that is not an outgoing subscription.");
        return -1;
    }
    switch (lev->subscription_state){
        case LinphoneSubscriptionIncomingReceived:
        case LinphoneSubscriptionTerminated:
        case LinphoneSubscriptionOutgoingInit:
            ms_error("linphone_event_send_subscribe(): cannot update subscription while in state [%s]", linphone_subscription_state_to_string(lev->subscription_state));
            return -1;
        break;
        case LinphoneSubscriptionNone:
        case LinphoneSubscriptionActive:
        case LinphoneSubscriptionExpiring:
        case LinphoneSubscriptionError:
        case LinphoneSubscriptionPending:
            /*those states are ok*/
        break;
    }

updatePublish

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    updatePublish
 * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){
    LinphoneContent * content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent *)evptr),
                        jtype, jsubtype, jdata, jencoding, NULL);
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    jint err;

    err=linphone_event_update_publish(ev, content);

    if (content) linphone_content_unref(content);
    return err;
}

linphone_event_update_publish

int linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body){
    return _linphone_event_send_publish(lev,body,TRUE);
}
static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body, bool_t notify_err){
    SalBodyHandler *body_handler;
    int err;

    if (lev->dir!=LinphoneSubscriptionInvalidDir){
        ms_error("linphone_event_update_publish(): this is not a PUBLISH event.");
        return -1;
    }
    if (lev->send_custom_headers){
        sal_op_set_sent_custom_header(lev->op,lev->send_custom_headers);
        lev->send_custom_headers=NULL;
    }else sal_op_set_sent_custom_header(lev->op,NULL);
    body_handler = sal_body_handler_from_content(body);
    err=sal_publish(lev->op,NULL,NULL,lev->name,lev->expires,body_handler);
    if (err==0){
        linphone_event_set_publish_state(lev,LinphonePublishProgress);
    }else if (notify_err){
        linphone_event_set_publish_state(lev,LinphonePublishError);
    }
    return err;
}

terminate

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    terminate
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_terminate(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    linphone_event_terminate(ev);
    return 0;
}

linphone_event_terminate

void linphone_event_terminate(LinphoneEvent *lev){
    lev->terminating=TRUE;
    if (lev->dir==LinphoneSubscriptionIncoming){
        sal_notify_close(lev->op);
    }else if (lev->dir==LinphoneSubscriptionOutgoing){
        sal_unsubscribe(lev->op);
    }

    if (lev->publish_state!=LinphonePublishNone){
        if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){
            sal_publish(lev->op,NULL,NULL,NULL,0,NULL);
        }else sal_op_unpublish(lev->op);
        linphone_event_set_publish_state(lev,LinphonePublishCleared);
        return;
    }

    if (lev->subscription_state!=LinphoneSubscriptionNone){
        linphone_event_set_state(lev,LinphoneSubscriptionTerminated);
        return;
    }
}

getReason

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    getReason
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_getReason(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return linphone_event_get_reason(ev);
}
LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev){
    return linphone_error_info_get_reason(linphone_event_get_error_info(lev));
}

linphone_error_info_get_reason

submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei);

submodules/linphone/coreapi/misc.c:LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei){
/**
 * Get reason code from the error info.
 * @param ei the error info.
 * @return a #LinphoneReason
 * @ingroup misc
**/
LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei){
    const SalErrorInfo *sei=(const SalErrorInfo*)ei;
    return linphone_reason_from_sal(sei->reason);
}

linphone_reason_from_sal

submodules/linphone/coreapi/private.h:LinphoneReason linphone_reason_from_sal(SalReason reason);
submodules/linphone/coreapi/misc.c:LinphoneReason linphone_reason_from_sal(SalReason r){
LinphoneReason linphone_reason_from_sal(SalReason r){
    LinphoneReason ret=LinphoneReasonNone;
    switch(r){
        case SalReasonNone:
            ret=LinphoneReasonNone;
            break;
        case SalReasonIOError:
            ret=LinphoneReasonIOError;
            break;
        case SalReasonUnknown:
        case SalReasonInternalError:
            ret=LinphoneReasonUnknown;
            break;
        case SalReasonBusy:
            ret=LinphoneReasonBusy;
            break;
        case SalReasonDeclined:
            ret=LinphoneReasonDeclined;
            break;
        case SalReasonDoNotDisturb:
            ret=LinphoneReasonDoNotDisturb;
            break;
        case SalReasonForbidden:
            ret=LinphoneReasonBadCredentials;
            break;
        case SalReasonNotAcceptable:
            ret=LinphoneReasonNotAcceptable;
            break;
        case SalReasonNotFound:
            ret=LinphoneReasonNotFound;
            break;
        case SalReasonRedirect:
            ret=LinphoneReasonNone;
            break;
        case SalReasonTemporarilyUnavailable:
            ret=LinphoneReasonTemporarilyUnavailable;
            break;
        case SalReasonServiceUnavailable:
            ret=LinphoneReasonIOError;
            break;
        case SalReasonRequestPending:
            ret=LinphoneReasonTemporarilyUnavailable; /*might not be exactly the perfect matching, but better than LinphoneReasonNone*/
            break;
        case SalReasonUnauthorized:
            ret=LinphoneReasonUnauthorized;
            break;
        case SalReasonUnsupportedContent:
            ret=LinphoneReasonUnsupportedContent;
        break;
        case SalReasonNoMatch:
            ret=LinphoneReasonNoMatch;
        break;
        case SalReasonRequestTimeout:
            ret=LinphoneReasonNotAnswered;
        break;
        case SalReasonMovedPermanently:
            ret=LinphoneReasonMovedPermanently;
        break;
        case SalReasonGone:
            ret=LinphoneReasonGone;
        break;
        case SalReasonAddressIncomplete:
            ret=LinphoneReasonAddressIncomplete;
        break;
        case SalReasonNotImplemented:
            ret=LinphoneReasonNotImplemented;
        break;
        case SalReasonBadGateway:
            ret=LinphoneReasonBadGateway;
        break;
        case SalReasonServerTimeout:
            ret=LinphoneReasonServerTimeout;
        break;
    }
    return ret;
}

getSubscriptionDir

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    getSubscriptionDir
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_getSubscriptionDir(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return linphone_event_get_subscription_dir(ev);
}

linphone_event_get_subscription_dir

LinphoneSubscriptionDir linphone_event_get_subscription_dir(LinphoneEvent *lev){
    return lev->dir;
}

getSubscriptionState

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    getSubscriptionState
 * Signature: (J)I
 */
JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_getSubscriptionState(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return linphone_event_get_subscription_state(ev);
}

JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_createSubscribe(JNIEnv *env, jobject thiz, jlong jcore, jlong jaddr, jstring jeventname, jint expires) {
    LinphoneCore *lc = (LinphoneCore*) jcore;
    LinphoneAddress *addr = (LinphoneAddress*) jaddr;
    LinphoneEvent *event;
    jobject jevent = NULL;
    const char *event_name = env->GetStringUTFChars(jeventname, NULL);

    event = linphone_core_create_subscribe(lc, addr, event_name, expires);
    env->ReleaseStringUTFChars(jeventname, event_name);
    if (event) {
        jevent = getEvent(env, event);
    }
    return jevent;
}

unref

/*
 * Class:     org_linphone_core_LinphoneEventImpl
 * Method:    unref
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneEventImpl_unref(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    linphone_event_unref(ev);
}

addCustomHeader

JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneEventImpl_addCustomHeader(JNIEnv *env, jobject thiz, jlong jevent, jstring jname, jstring jvalue) {
    const char *name = jname ? env->GetStringUTFChars(jname, NULL) : NULL;
    const char *value = jvalue ? env->GetStringUTFChars(jvalue, NULL) : NULL;
    linphone_event_add_custom_header((LinphoneEvent*) jevent, name, value);
    if (jname) env->ReleaseStringUTFChars(jname, name);
    if (jvalue) env->ReleaseStringUTFChars(jvalue, value);
}

getCustomHeader

JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneEventImpl_getCustomHeader(JNIEnv *env, jobject thiz, jlong jevent, jstring jname) {
    const char *name = jname ? env->GetStringUTFChars(jname, NULL) : NULL;
    const char *header = linphone_event_get_custom_header((LinphoneEvent*) jevent, name);
    jstring jheader = header ? env->NewStringUTF(header) : NULL;
    if (jname) env->ReleaseStringUTFChars(jname, name);
    return jheader;
}

sendSubscribe

JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneEventImpl_sendSubscribe(JNIEnv *env, jobject thiz, jlong eventptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding) {
    LinphoneContent *content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent*)eventptr),
                            jtype, jsubtype, jdata, jencoding, NULL);

    linphone_event_send_subscribe((LinphoneEvent*) eventptr, content);
    if (content) linphone_content_unref(content);
}

linphone_event_send_subscribe

int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *body){
    SalBodyHandler *body_handler;
    int err;

    if (lev->dir!=LinphoneSubscriptionOutgoing){
        ms_error("linphone_event_send_subscribe(): cannot send or update something that is not an outgoing subscription.");
        return -1;
    }
    switch (lev->subscription_state){
        case LinphoneSubscriptionIncomingReceived:
        case LinphoneSubscriptionTerminated:
        case LinphoneSubscriptionOutgoingInit:
            ms_error("linphone_event_send_subscribe(): cannot update subscription while in state [%s]", linphone_subscription_state_to_string(lev->subscription_state));
            return -1;
        break;
        case LinphoneSubscriptionNone:
        case LinphoneSubscriptionActive:
        case LinphoneSubscriptionExpiring:
        case LinphoneSubscriptionError:
        case LinphoneSubscriptionPending:
            /*those states are ok*/
        break;
    }

    if (lev->send_custom_headers){
        sal_op_set_sent_custom_header(lev->op,lev->send_custom_headers);
        lev->send_custom_headers=NULL;
    }else sal_op_set_sent_custom_header(lev->op,NULL);

    body_handler = sal_body_handler_from_content(body);
    err=sal_subscribe(lev->op,NULL,NULL,lev->name,lev->expires,body_handler);
    if (err==0){
        if (lev->subscription_state==LinphoneSubscriptionNone)
            linphone_event_set_state(lev,LinphoneSubscriptionOutgoingInit);
    }
    return err;
}

sendPublish

JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneEventImpl_sendPublish(JNIEnv *env, jobject thiz, jlong eventptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding) {
    LinphoneContent *content = create_content_from_java_args(env, linphone_event_get_core((LinphoneEvent*)eventptr),
                            jtype, jsubtype, jdata, jencoding, NULL);
    linphone_event_send_publish((LinphoneEvent*) eventptr, content);
    if (content) linphone_content_unref(content);
}

getErrorInfo

JNIEXPORT jlong JNICALL Java_org_linphone_core_LinphoneEventImpl_getErrorInfo(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneEvent *ev=(LinphoneEvent*)evptr;
    return (jlong)linphone_event_get_error_info(ev);
}

getCore

JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneEventImpl_getCore(JNIEnv *env, jobject jobj, jlong evptr){
    LinphoneCore *lc=linphone_event_get_core((LinphoneEvent*)evptr);
    LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
    jobject core = ljb->getCore();
    return core;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵健zj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值