说明
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;
}