linphone-LinphoneAddressImpl文件对应的JNI层文件分析
2017-12-27 14:57
716 查看
说明
本篇是java及对应的c语言的分析的第一篇,旨在通过每一个文件对jni层部分的主要逻辑进行分析。
UML类图
newLinphoneAddressImpl函数分析
/** *@params uri 网址 *@params displayName 要显示的名称 */ private native long newLinphoneAddressImpl(String uri,String displayName);1
2
3
4
5
[/code]
linphonecore_jni.cc 中对应的文件
extern "C" jlong Java_org_linphone_core_LinphoneAddressImpl_newLinphoneAddressImpl(JNIEnv* env,jobject thiz,jstring juri,jstring jdisplayName) { const char* uri = juri?env->GetStringUTFChars(juri, NULL):NULL; LinphoneAddress* address = linphone_address_new(uri); if (jdisplayName && address) { const char* displayName = env->GetStringUTFChars(jdisplayName, NULL); linphone_address_set_display_name(address,displayName); env->ReleaseStringUTFChars(jdisplayName, displayName); } if (uri) env->ReleaseStringUTFChars(juri, uri); return (jlong) address; }1
2
3
4
5
6
7
8
9
10
11
12
[/code]
这里清楚明了, 主要是创建一个LinphonAddress, 其中需要注意的是,调用字符串一定要释放字符串。
其中:LinphoneAddress * 的定义是
linphoncore.h /** * Object that represents a SIP address. * * The LinphoneAddress is an opaque object to represents SIP addresses, ie * the content of SIP's 'from' and 'to' headers. * A SIP address is made of display name, username, domain name, port, and various * uri headers (such as tags). It looks like 'Alice <sip:alice@example.net>'. * The LinphoneAddress has methods to extract and manipulate all parts of the address. * When some part of the address (for example the username) is empty, the accessor methods * return NULL. * * @ingroup linphone_address */ typedef struct SalAddress LinphoneAddress;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]
是由SalAddress定义的。
其中SalAddress怎么来的呢?
sal.h struct SalAddress; typedef struct SalAddress SalAddress1
2
3
[/code]
查找linphone_address_new函数
linphonecore.h LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr);1
2
[/code]
其中LINPHONE_PUBLIC是一个扩展修饰符:如果有兴趣,请看下面的文章。但是我不建议看,我C++不是很好, 我也没有看。
c++ 中__declspec 的用法
然后,这个函数是在哪里实例化的呢, 一位我的目的是通过linphone来学习C/C++所以,我还是要一探究竟。
通过grep -r “linphone_address_new(“ 找到了如下的结果:
linphone/coreapi/address.c:LinphoneAddress * linphone_address_new(const char *addr){1
[/code]
他妈的,终于找到这个函数的实现了:
/** * Constructs a LinphoneAddress object by parsing the user supplied address, * given as a string. **/ LinphoneAddress * linphone_address_new(const char *addr){ SalAddress *saddr=sal_address_new(addr); if (saddr==NULL) ms_error("Cannot create LinphoneAddress, bad uri [%s]",addr); return saddr; }1
2
3
4
5
6
7
8
9
10
[/code]
无语了, 这里竟然又调用了一个函数, 真是坑爹啊。不过还是要找一找,找之前,看一下这个函数的其它地方。 好的,就一个报错函数, 这个报错函数看不看, 最后看心情。
开始找sal_address_new()函数, 通过grep -r “sal_address_new(“ 找到了
linphone/include/sal/sal.h:SalAddress * sal_address_new(const char *uri); linphone/coreapi/bellesip_sal/sal_address_impl.c:SalAddress * sal_address_new(const char *uri){1
2
3
[/code]
和其实现
/* Address manipulation API*/ SalAddress * sal_address_new(const char *uri){ belle_sip_header_address_t* result; if (uri) { result=belle_sip_header_address_parse (uri); /*may return NULL*/ } else { result = belle_sip_header_address_new(); belle_sip_header_address_set_uri(result,belle_sip_uri_new()); } if (result) belle_sip_object_ref(result); return (SalAddress *)result; }1
2
3
4
5
6
7
8
9
10
11
12
13
[/code]
其中用到了,bellesip中的库, 这里就不往下分析了, 已经超出的初步计划的内容了。我们的目标是~没有蛀牙(要慢慢的来)
等会会儿,还不着急, 分析了下下底层,我们也得要看看谁调用了它。这里主来是看LinphoneAddress<-LinphoneAddressImpl 。
看看java代码
protected LinphoneAddressImpl(String identity) throws LinphoneCoreException{ nativePtr = newLinphoneAddressImpl(identity, null); if(nativePtr==0) { throw new LinphoneCoreException("Cannot create LinphoneAdress from ["+identity+"]"); } } protected LinphoneAddressImpl(String username,String domain,String displayName) { nativePtr = newLinphoneAddressImpl(null, displayName); this.setUserName(username); this.setDomain(domain); }1
2
3
4
5
6
7
8
9
10
11
[/code]
这下就懵懵懂懂的明白了, 声称一个nativePtr标识符。 这个可大有用处呢。应不应该深入研究一下这个nativePtr, 算了, 技术不行,慢慢啃吧。
总结
这里是通过LinphoneAddress 强转成jlong, 的地址返回给java上层。
主要生成nativePtr
ref 函数分析
对应的jni函数
/* * Class: org_linphone_core_LinphoneAddressImpl * Method: ref * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_org_linphone_core_LinphoneAddressImpl_ref (JNIEnv *, jobject, jlong);1
2
3
4
5
6
7
[/code]
具体的方法实现
linphonecore_jni.cc extern "C" jlong Java_org_linphone_core_LinphoneAddressImpl_ref( JNIEnv* env, jobject thiz,jlong ptr) { return (jlong)linphone_address_ref((LinphoneAddress*)ptr); }1
2
3
4
5
6
[/code]
这里调用了linphone_address_ref()函数, 看看这个函数在哪里呢?
在submodules/linphone/coreapi/linphonecore.h中有声明
LINPHONE_PUBLIC LinphoneAddress * linphone_address_ref(LinphoneAddress *addr);1
[/code]
在submodules/linphone/coreapi/address.c中有实现
/** * Increment reference count of LinphoneAddress object. **/ LinphoneAddress * linphone_address_ref(LinphoneAddress *addr){ return sal_address_ref(addr); }1
2
3
4
5
6
[/code]
这里又莫名奇妙的遇到了sal_address_ref(addr)函数, 让我们来看看这个函数吧。靠!它不在这个文件中,让我来找找它在哪里。
通过 grep -r “sal_addres_ref” 找到了下面的结果。
submodules/linphone/include/sal/sal.h:SalAddress * sal_address_ref(SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:SalAddress *sal_address_ref(SalAddress *addr){ submodules/linphone/coreapi/address.c: return sal_address_ref(addr);1
2
3
[/code]
这里我们找到了这个函数的实现
SalAddress *sal_address_ref(SalAddress *addr){ return (SalAddress*)belle_sip_object_ref(BELLE_SIP_HEADER_ADDRESS(addr)); }1
2
3
[/code]
通过 重点内容 命令,我们大海捞针的找到了这个
submodules/belle-sip/include/belle-sip/headers.h:#define BELLE_SIP_HEADER_ADDRESS(t) BELLE_SIP_CAST(t,belle_sip_header_address_t)1
[/code]
原来是一个define定义。
// BELLE_SIP_HEADER_ADDRESS 用的就是这个 submodules/belle-sip/include/belle-sip/object.h:#define BELLE_SIP_CAST(obj,_type) ((_type*)belle_sip_object_cast((belle_sip_object_t *)(obj), _type##_id, #_type, __FILE__, __LINE__)1
2
3
[/code]
怎么又是一个define定义, 在C/C++语言中, 这种定义也太频繁了吧。
找到了这个
submodules/belle-sip/include/belle-sip/object.h:BELLESIP_EXPORT void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno); submodules/belle-sip/include/belle-sip/object.h:#define BELLE_SIP_CAST(obj,_type) ((_type*)belle_sip_object_cast((belle_sip_object_t *)(obj), _type##_id, #_type, __FILE__, __LINE__)) submodules/belle-sip/src/belle_sip_object.c:void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno){1
2
3
4
5
6
[/code]
其中
void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno){ if (obj!=NULL){ if (has_type(obj,id)==0){ belle_sip_fatal("Bad cast to %s at %s:%i",castname,file,fileno); return NULL; } } return obj; }1
2
3
4
5
6
7
8
9
[/code]
看这个
submodules/belle-sip/include/belle-sip/utils.h:static BELLESIP_INLINE void BELLE_SIP_CHECK_FORMAT_ARGS(1,2) belle_sip_fatal(const char *fmt,...)1
[/code]
static BELLESIP_INLINE void BELLE_SIP_CHECK_FORMAT_ARGS(1,2) belle_sip_fatal(const char *fmt,...) { va_list args; va_start (args, fmt); belle_sip_logv(BELLE_SIP_LOG_FATAL, fmt, args); va_end (args); }1
2
3
4
5
6
7
8
[/code]
好想知道va_start函数和belle_sip_logv函数和va_end函数是干什么的啊,好, 想就做:
static void __belle_sip_logv_out(belle_sip_log_level lev, const char *fmt, va_list args); belle_sip_log_function_t belle_sip_logv_out=__belle_sip_logv_out;1
2
3
4
[/code]
static void __belle_sip_logv_out(belle_sip_log_level lev, const char *fmt, va_list args){ const char *lname="undef"; char *msg; struct timeval tp; struct tm *lt; #ifndef _WIN32 struct tm tmstorage; #endif time_t curtime; belle_sip_gettimeofday(&tp,NULL); curtime=tp.tv_sec; #ifdef _WIN32 lt = localtime(&curtime); #else lt = localtime_r(&curtime,&tmstorage); #endif if (__log_file==NULL) __log_file=stderr; switch(lev){ case BELLE_SIP_LOG_DEBUG: lname="debug"; break; case BELLE_SIP_LOG_MESSAGE: lname="message"; break; case BELLE_SIP_LOG_WARNING: lname="warning"; break; case BELLE_SIP_LOG_ERROR: lname="error"; break; case BELLE_SIP_LOG_FATAL: lname="fatal"; break; default: belle_sip_fatal("Bad level !"); } msg=belle_sip_strdup_vprintf(fmt,args); #if defined(_MSC_VER) && !defined(_WIN32_WCE) #ifndef _UNICODE OutputDebugStringA(msg); OutputDebugStringA("\r\n"); #else { int len=strlen(msg); wchar_t *tmp=(wchar_t*)belle_sip_malloc0((len+1)*sizeof(wchar_t)); mbstowcs(tmp,msg,len); OutputDebugStringW(tmp); OutputDebugStringW(L"\r\n"); belle_sip_free(tmp); } #endif #endif fprintf(__log_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i belle-sip-%s-%s" ENDLINE,1900+lt->tm_year,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec,(int)(tp.tv_usec/1000), lname,msg); fflush(__log_file); // fatal messages should go to stderr too, even if we are using a file since application will abort right after if (__log_file != stderr && lev == BELLE_SIP_LOG_FATAL) { fprintf(stderr,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i belle-sip-%s-%s" ENDLINE,1900+lt->tm_year,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec,(int)(tp.tv_usec/1000), lname,msg); fflush(stderr); } free(msg); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[/code]
算了,不分析了, 太难了,把这个放到下一个步骤吧。这里有点好高骛远了。但是这个函数是干什么的,这个得搞明白了啊。
最后结果:我也不知道这是干什么的。
感言: 感觉自己不是在写博客,而是在自娱自乐。就算是吧, 我怎么也得有个开头啊。要不怎么能写好博客呢!
unref函数分析
不想细细的分析了, 就这个样子吧。不过还得稍微看一下;extern "C" void Java_org_linphone_core_LinphoneAddressImpl_unref( JNIEnv* env, jobject thiz, jlong ptr) { linphone_address_unref((LinphoneAddress*)ptr); }1
2
3
4
5
6
7
8
[/code]
这个就是具体实现, 跟上面有相反的作用。
看这里
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC void linphone_address_unref(LinphoneAddress *addr);1
[/code]
submodules/linphone/coreapi/address.c:void linphone_address_unref(LinphoneAddress *addr){1
[/code]
找到了实现
/** * Decrement reference count of LinphoneAddress object. When dropped to zero, memory is freed. **/ void linphone_address_unref(LinphoneAddress *addr){ sal_address_unref(addr); }1
2
3
4
5
6
7
[/code]
接下来调用的这个函数是在这里声明的
submodules/linphone/include/sal/sal.h:void sal_address_unref(SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:void sal_address_unref(SalAddress *addr){ submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c: sal_address_unref(addr); submodules/linphone/coreapi/address.c: sal_address_unref(addr); submodules/linphone/coreapi/address.c: sal_address_unref(u);1
2
3
4
5
6
7
8
9
10
[/code]
哈哈,在这里
void sal_address_unref(SalAddress *addr){ belle_sip_object_unref(BELLE_SIP_HEADER_ADDRESS(addr)); }1
2
3
4
[/code]
这个函数就到这里吧, 搞得我头疼的很。
总结
就是跟ref函数相对应的, 我看着想什么格式化之类的,准不准就不说了, 反正是每搞明白。但是还是不影响往下分析。
脑洞大开
还是坚持把每个native函数对应的jni层及调用的库函数大致追踪一遍,不要求弄明白,大概有个了解, 知道有这个东西就可以了。毕竟,是一个初学者,想细究的也不差这点时间。
clone函数分析
对应jni函数
extern "C" jlong Java_org_linphone_core_LinphoneAddressImpl_clone(JNIEnv* env ,jobject thiz ,jlong ptr) { return (jlong) (ptr ? linphone_address_clone((const LinphoneAddress*)ptr) : NULL); }1
2
3
4
5
[/code]
linphone_address_clone
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr); submodules/linphone/coreapi/address.c:LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr){1
2
3
[/code]
/** * Clones a LinphoneAddress object. **/ LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr){ return sal_address_clone(addr); }1
2
3
4
5
6
7
[/code]
不往下看了, 大约就是复制了一份传上来了。想到这里, 不禁发现,我还不知道nativePtr是干什么的,不行改天得去看看文档,看看前人都是怎么做的。
getDisplayName函数分析
对应jni函数
extern "C" jstring Java_org_linphone_core_LinphoneAddressImpl_getDisplayName(JNIEnv* env ,jobject thiz ,jlong ptr) { const char* displayName = linphone_address_get_display_name((LinphoneAddress*)ptr); if (displayName) { return env->NewStringUTF(displayName); } else { return NULL; } }1
2
3
4
5
6
7
8
9
10
[/code]
linphone_address_get_display_name
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC const char *linphone_address_get_display_name(const LinphoneAddress* u); submodules/linphone/coreapi/address.c:const char *linphone_address_get_display_name(const LinphoneAddress* u){1
2
3
[/code]
这也太懒了吧, 我竟然连名字都不写了,够可以的。
/** * Returns the display name. **/ const char *linphone_address_get_display_name(const LinphoneAddress* u){ return sal_address_get_display_name(u); }1
2
3
4
5
6
[/code]
sal_address_get_display_name
submodules/linphone/include/sal/sal.h:const char *sal_address_get_display_name(const SalAddress* addr); submodules/linphone/include/sal/sal.h:const char *sal_address_get_display_name_unquoted(const SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_display_name(const SalAddress* addr){ submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_display_name_unquoted(const SalAddress *addr){ submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c: return sal_address_get_display_name(addr);1
2
3
4
5
6
7
8
9
[/code]
const char *sal_address_get_display_name(const SalAddress* addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); return belle_sip_header_address_get_displayname(header_addr); } const char *sal_address_get_display_name_unquoted(const SalAddress *addr){ return sal_address_get_display_name(addr); }1
2
3
4
5
6
7
8
9
[/code]
belle_sip_header_address_get_displayname
submodules/belle-sip/include/belle-sip/headers.h:BELLESIP_EXPORT const char* belle_sip_header_address_get_displayname(const belle_sip_header_address_t* address);1
2
[/code]
sal_address_get_display_name
submodules/linphone/include/sal/sal.h:const char *sal_address_get_display_name(const SalAddress* addr); submodules/linphone/include/sal/sal.h:const char *sal_address_get_display_name_unquoted(const SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_display_name(const SalAddress* addr){ submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_display_name_unquoted(const SalAddress *addr){1
2
3
4
5
6
7
8
[/code]
反正先生出来的两个函数,都是调用同一个函数进入。
getUserName函数分析
对应jni函数
extern "C" jstring Java_org_linphone_core_LinphoneAddressImpl_getUserName(JNIEnv* env ,jobject thiz ,jlong ptr) { const char* userName = linphone_address_get_username((LinphoneAddress*)ptr); if (userName) { return env->NewStringUTF(userName); } else { return NULL; } }1
2
3
4
5
6
7
8
9
10
[/code]
linphone_address_get_username
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC const char *linphone_address_get_username(const LinphoneAddress *u);1
[/code]
submodules/linphone/coreapi/address.c:const char *linphone_address_get_username(const LinphoneAddress *u){1
[/code]
/** * Returns the username. **/ const char *linphone_address_get_username(const LinphoneAddress *u){ return sal_address_get_username(u); }1
2
3
4
5
6
7
[/code]
sal_address_get_username
submodules/linphone/include/sal/sal.h:const char *sal_address_get_username(const SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_username(const SalAddress *addr){1
2
[/code]
const char *sal_address_get_username(const SalAddress *addr){ SAL_ADDRESS_GET(addr,user) }1
2
3
[/code]
SAL_ADDRESS_GET
#define SAL_ADDRESS_GET(addr,param) \ {belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\ belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\ if (uri) {\ return belle_sip_uri_get_##param(uri);\ } else\ return NULL;}1
2
3
4
5
6
7
8
[/code]
我擦,神乎其神的, 竟然出现了一个“##param” ,真心看不懂啊, 这个真是难坏我了, 不过不用着急,毕竟这是C++部分了,并不是很闹心。除了分析linphone之外,我还不断的加强我在工程性的C++部分下手, 主要还是要看基础, 一切牛逼得到技术都离不开技术。
getDomain函数分析
对应的jni函数
extern "C" jstring Java_org_linphone_core_LinphoneAddressImpl_getDomain(JNIEnv* env ,jobject thiz ,jlong ptr) { const char* domain = linphone_address_get_domain((LinphoneAddress*)ptr); if (domain) { return env->NewStringUTF(domain); } else { return NULL; } }1
2
3
4
5
6
7
8
9
10
[/code]
追踪
linphone_address_get_domainsubmodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC const char *linphone_address_get_domain(const LinphoneAddress *u); submodules/linphone/coreapi/address.c:const char *linphone_address_get_domain(const LinphoneAddress *u){1
2
3
[/code]
/** * Returns the domain name. **/ const char *linphone_address_get_domain(const LinphoneAddress *u){ return sal_address_get_domain(u); }1
2
3
4
5
6
[/code]
sal_address_get_domain
submodules/linphone/include/sal/sal.h:const char *sal_address_get_domain(const SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char *sal_address_get_domain(const SalAddress *addr){1
2
3
[/code]
const char *sal_address_get_domain(const SalAddress *addr){ SAL_ADDRESS_GET(addr,host) }1
2
3
[/code]
SAL_ADDRESS_GET
submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:#define SAL_ADDRESS_GET(addr,param) \1
[/code]
#define SAL_ADDRESS_GET(addr,param) \ {belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\ belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\ if (uri) {\ return belle_sip_uri_get_##param(uri);\ } else\ return NULL;}1
2
3
4
5
6
7
[/code]
这个跟上面的调用的是同一个函数。旧这个就让我费解了,
容我任性的再往下追踪一下, 看看能不能找到最下面的东西。
BELLE_SIP_HEADER_ADDRESS
submodules/belle-sip/include/belle-sip/headers.h:#define BELLE_SIP_HEADER_ADDRESS(t) BELLE_SIP_CAST(t,belle_sip_header_address_t)1
[/code]
BELLE_SIP_CAST
submodules/belle-sip/include/belle-sip/object.h:#define BELLE_SIP_CAST(obj,_type) ((_type*)belle_sip_object_cast((belle_sip_object_t *)(obj), _type##_id, #_type, __FILE__, __LINE__))1
[/code]
belle_sip_object_cast
submodules/belle-sip/include/belle-sip/object.h:BELLESIP_EXPORT void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno);1
[/code]
void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno){ if (obj!=NULL){ if (has_type(obj,id)==0){ belle_sip_fatal("Bad cast to %s at %s:%i",castname,file,fileno); return NULL; } } return obj; }1
2
3
4
5
6
7
8
9
10
[/code]
belle_sip_fatal
static BELLESIP_INLINE void BELLE_SIP_CHECK_FORMAT_ARGS(1,2) belle_sip_fatal(const char *fmt,...) { va_list args; va_start (args, fmt); belle_sip_logv(BELLE_SIP_LOG_FATAL, fmt, args); va_end (args); }1
2
3
4
5
6
7
[/code]
has_type
static int has_type(belle_sip_object_t *obj, belle_sip_type_id_t id){ belle_sip_object_vptr_t *vptr=obj->vptr; while(vptr!=NULL){ if (vptr->id==id) return TRUE; vptr=vptr->get_parent(); } return FALSE; }1
2
3
4
5
6
7
8
9
[/code]
到底应该分析的这么清楚, 如果深入了会不会导致忘记了当初分析linphone的初衷。应该不会吧,毕竟并不是每一次都要分析这么深入。现在正在逐渐探索分析的方式。
其中《va_start》和《va_end》是系统的函数
va_start和va_end使用详解
竟然找到了va_start和va_end函数是系统函数,操作c语言中的可变参数。
一鼓作气, 继续深入, 哈哈。
belle_sip_logv
submodules/belle-sip/include/belle-sip/utils.h:BELLESIP_EXPORT void belle_sip_logv(int level, const char *fmt, va_list args); submodules/belle-sip/include/belle-sip/utils.h:static BELLESIP_INLINE void belle_sip_logv(belle_sip_log_level level, const char *fmt, va_list args) {1
2
3
[/code]
#if !defined(_WIN32) && !defined(_WIN32_WCE) static BELLESIP_INLINE void belle_sip_logv(belle_sip_log_level level, const char *fmt, va_list args) { if (belle_sip_logv_out!=NULL && belle_sip_log_level_enabled(level)) belle_sip_logv_out(level,fmt,args); if (level==BELLE_SIP_LOG_FATAL) abort(); } #else BELLESIP_EXPORT void belle_sip_logv(int level, const char *fmt, va_list args); #endif1
2
3
4
5
6
7
8
9
10
[/code]
belle_sip_logv_out
submodules/belle-sip/include/belle-sip/utils.h:BELLESIP_VAR_EXPORT belle_sip_log_function_t belle_sip_logv_out; submodules/belle-sip/src/belle_sip_utils.c:belle_sip_log_function_t belle_sip_logv_out=__belle_sip_logv_out1
2
3
[/code]
__belle_sip_logv_out
static void __belle_sip_logv_out(belle_sip_log_level lev, const char *fmt, va_list args);1
2
3
[/code]
static void __belle_sip_logv_out(belle_sip_log_level lev, const char *fmt, va_list args){ const char *lname="undef"; char *msg; struct timeval tp; struct tm *lt; #ifndef _WIN32 struct tm tmstorage; #endif time_t curtime; belle_sip_gettimeofday(&tp,NULL); curtime=tp.tv_sec; #ifdef _WIN32 lt = localtime(&curtime); #else lt = localtime_r(&curtime,&tmstorage); #endif if (__log_file==NULL) __log_file=stderr; switch(lev){ case BELLE_SIP_LOG_DEBUG: lname="debug"; break; case BELLE_SIP_LOG_MESSAGE: lname="message"; break; case BELLE_SIP_LOG_WARNING: lname="warning"; break; case BELLE_SIP_LOG_ERROR: lname="error"; break; case BELLE_SIP_LOG_FATAL: lname="fatal"; break; default: belle_sip_fatal("Bad level !"); } msg=belle_sip_strdup_vprintf(fmt,args); #if defined(_MSC_VER) && !defined(_WIN32_WCE) #ifndef _UNICODE OutputDebugStringA(msg); OutputDebugStringA("\r\n"); #else { int len=strlen(msg); wchar_t *tmp=(wchar_t*)belle_sip_malloc0((len+1)*sizeof(wchar_t)); mbstowcs(tmp,msg,len); OutputDebugStringW(tmp); OutputDebugStringW(L"\r\n"); belle_sip_free(tmp); } #endif #endif fprintf(__log_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i belle-sip-%s-%s" ENDLINE,1900+lt->tm_year,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec,(int)(tp.tv_usec/1000), lname,msg); fflush(__log_file); // fatal messages should go to stderr too, even if we are using a file since application will abort right after if (__log_file != stderr && lev == BELLE_SIP_LOG_FATAL) { fprintf(stderr,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i belle-sip-%s-%s" ENDLINE,1900+lt->tm_year,lt->tm_mon+1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec,(int)(tp.tv_usec/1000), lname,msg); fflush(stderr); } free(msg); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[/code]
belle_sip_header_address_get_uri
submodules/belle-sip/include/belle-sip/headers.h:BELLESIP_EXPORT belle_sip_uri_t* belle_sip_header_address_get_uri(const belle_sip_header_address_t* address);1
[/code]
flannery@flannery:~/oschina/linephone-android$ grep -r "*.belle_sip_header_address_get_uri" submodules/belle-sip/include/belle-sip/headers.h:BELLESIP_EXPORT belle_sip_uri_t* belle_sip_header_address_get_uri(const belle_sip_header_address_t* address); submodules/belle-sip/src/belle_sip_headers_impl.c:belle_sip_uri_t* belle_sip_header_address_get_uri(const belle_sip_header_address_t* address) {1
2
3
[/code]
belle_sip_uri_t* belle_sip_header_address_get_uri(const belle_sip_header_address_t* address) { return address->uri; }1
2
3
[/code]
今天快要疯了, 竟然还想要无耻的往下找,好吧,那就找吧。
belle_sip_header_address_t
submodules/belle-sip/include/belle-sip/headers.h:typedef struct _belle_sip_header_address belle_sip_header_address_t;1
[/code]
_belle_sip_header_address
submodules/belle-sip/include/belle-sip/headers.h:typedef struct _belle_sip_header_address belle_sip_header_address_t; submodules/belle-sip/src/belle_sip_headers_impl.c:struct _belle_sip_header_address {1
2
[/code]
/************************ * header_address ***********************/ struct _belle_sip_header_address { belle_sip_parameters_t base; char* displayname; belle_sip_uri_t* uri; belle_generic_uri_t* absolute_uri; };1
2
3
4
5
6
7
8
9
[/code]
getTransport函数分析
对应jni函数
extern "C" jint Java_org_linphone_core_LinphoneAddressImpl_getTransport(JNIEnv* env ,jobject thiz ,jlong ptr) { LinphoneTransportType transporttype = linphone_address_get_transport((LinphoneAddress*)ptr); return (jint)transporttype; }1
2
3
4
5
6
[/code]
追踪
LinphoneTransportTypesubmodules/linphone/coreapi/linphonecore.h:typedef enum _LinphoneTransportType LinphoneTransportType; submodules/linphone/coreapi/linphonecore.h:enum _LinphoneTransportType{ /** * Enum describing transport type for LinphoneAddress. * @ingroup linphone_address **/ enum _LinphoneTransportType{ LinphoneTransportUdp, LinphoneTransportTcp, LinphoneTransportTls, LinphoneTransportDtls };1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
linphone_address_get_transport
submodules/linphone/coreapi/address.c:LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri){ submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri);1
2
[/code]
/** * Get the transport. **/ LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri){ return (LinphoneTransportType)sal_address_get_transport(uri); }1
2
3
4
5
6
[/code]
sal_address_get_transport
submodules/linphone/include/sal/sal.h:SalTransport sal_address_get_transport(const SalAddress* addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:SalTransport sal_address_get_transport(const SalAddress* addr){1
2
3
[/code]
SalTransport sal_address_get_transport(const SalAddress* addr){ const char *transport=sal_address_get_transport_name(addr); if (transport) return sal_transport_parse(transport); else return SalTransportUDP; };1
2
3
4
5
6
7
[/code]
SalTransport
submodules/linphone/include/sal/sal.h: SalTransportUDP, /*UDP*/ submodules/linphone/include/sal/sal.h: SalTransportTCP, /*TCP*/ submodules/linphone/include/sal/sal.h: SalTransportTLS, /*TLS*/ submodules/linphone/include/sal/sal.h: SalTransportDTLS, /*DTLS*/ submodules/linphone/include/sal/sal.h:}SalTransport;1
2
3
4
5
[/code]
可以看出就是个枚举。
typedef enum { SalTransportUDP, /*UDP*/ SalTransportTCP, /*TCP*/ SalTransportTLS, /*TLS*/ SalTransportDTLS, /*DTLS*/ }SalTransport;1
2
3
4
5
6
[/code]
SalAddress
submodules/linphone/include/sal/sal.h:struct SalAddress; submodules/linphone/include/sal/sal.h:typedef struct SalAddress SalAddress; submodules/linphone/coreapi/linphonecore.h:typedef struct SalAddress LinphoneAddress;1
2
3
4
[/code]
到这里, 一定要有个小插曲:grep的重要性, 熟练的使用grep的用法是多么的重要。下面给个链接。
grep的用法
自己慢慢去看吧。
sal_address_get_transport_name
submodules/linphone/include/sal/sal.h:const char* sal_address_get_transport_name(const SalAddress* addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c: const char *transport=sal_address_get_transport_name(addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:const char* sal_address_get_transport_name(const SalAddress* addr){1
2
3
4
[/code]
const char* sal_address_get_transport_name(const SalAddress* addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); if (uri) { return belle_sip_uri_get_transport_param(uri); } return NULL; }1
2
3
4
5
6
7
8
[/code]
belle_sip_uri_get_transport_param
submodules/belle-sip/include/belle-sip/sip-uri.h:BELLESIP_EXPORT const char* belle_sip_uri_get_transport_param(const belle_sip_uri_t* uri) ;1
[/code]
最后我就不明白这是什么东西了。
sal_transport_parse
submodules/linphone/include/sal/sal.h:SalTransport sal_transport_parse(const char*); submodules/linphone/coreapi/sal.c:SalTransport sal_transport_parse(const char* param) {1
2
3
[/code]
SalTransport sal_transport_parse(const char* param) { if (!param) return SalTransportUDP; if (strcasecmp("udp",param)==0) return SalTransportUDP; if (strcasecmp("tcp",param)==0) return SalTransportTCP; if (strcasecmp("tls",param)==0) return SalTransportTLS; if (strcasecmp("dtls",param)==0) return SalTransportDTLS; ms_error("Unknown transport type[%s], returning UDP", param); return SalTransportUDP; }1
2
3
4
5
6
7
8
9
10
[/code]
getPort 函数分析
Java_org_linphone_core_LinphoneAddressImpl_getPort
extern "C" jint Java_org_linphone_core_LinphoneAddressImpl_getPort(JNIEnv* env ,jobject thiz ,jlong ptr) { int port = linphone_address_get_port((LinphoneAddress*)ptr); return (jint)port; }1
2
3
4
5
6
7
[/code]
linphone_address_get_port
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC int linphone_address_get_port(const LinphoneAddress *u); submodules/linphone/coreapi/address.c:int linphone_address_get_port(const LinphoneAddress *u) {1
2
3
[/code]
/** * Get port number, 0 if not present. */ int linphone_address_get_port(const LinphoneAddress *u) { return sal_address_get_port(u); }1
2
3
4
5
6
[/code]
sal_address_get_port
submodules/linphone/include/sal/sal.h:int sal_address_get_port(const SalAddress *addr); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:int sal_address_get_port(const SalAddress *addr){1
2
[/code]
int sal_address_get_port(const SalAddress *addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); if (uri) { return belle_sip_uri_get_port(uri); } else return -1; }1
2
3
4
5
6
7
8
[/code]
belle_sip_uri_get_port
submodules/belle-sip/include/belle-sip/sip-uri.h:BELLESIP_EXPORT int belle_sip_uri_get_port(const belle_sip_uri_t* uri) ;1
[/code]
toUri函数分析
Java_org_linphone_core_LinphoneAddressImpl_toUri
extern "C" jstring Java_org_linphone_core_LinphoneAddressImpl_toUri(JNIEnv* env ,jobject thiz ,jlong ptr) { char* uri = linphone_address_as_string_uri_only((LinphoneAddress*)ptr); jstring juri =env->NewStringUTF(uri); ms_free(uri); return juri; }1
2
3
4
5
6
7
8
[/code]
linphone_address_as_string_uri_only
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u);1
[/code]
/** * Returns the SIP uri only as a string, that is display name is removed. * The returned char * must be freed by the application. Use ms_free(). **/ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ return sal_address_as_string_uri_only(u); }1
2
3
4
5
6
7
[/code]
sal_address_as_string_uri_only
submodules/linphone/include/sal/sal.h:char *sal_address_as_string_uri_only(const SalAddress *u); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:char *sal_address_as_string_uri_only(const SalAddress *addr){1
2
3
[/code]
char *sal_address_as_string_uri_only(const SalAddress *addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_uri_t* sip_uri = belle_sip_header_address_get_uri(header_addr); belle_generic_uri_t* absolute_uri = belle_sip_header_address_get_absolute_uri(header_addr); char tmp[1024]={0}; size_t off=0; belle_sip_object_t* uri; if (sip_uri) { uri=(belle_sip_object_t*)sip_uri; } else if (absolute_uri) { uri=(belle_sip_object_t*)absolute_uri; } else { ms_error("Cannot generate string for addr [%p] with null uri",addr); return NULL; } belle_sip_object_marshal(uri,tmp,sizeof(tmp),&off); return ms_strdup(tmp); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[/code]
belle_sip_object_marshal
submodules/belle-sip/include/belle-sip/object.h: /** * Writes a string representation of the object into the supplied buffer. * Same as belle_sip_object_to_string(), but without allocating space for the output string. **/ BELLESIP_EXPORT belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset);1
2
3
4
5
6
7
[/code]
submodules/belle-sip/src/belle_sip_object.c:belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset) {1
[/code]
belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset) { belle_sip_object_vptr_t *vptr=obj->vptr; while (vptr != NULL) { if (vptr->marshal != NULL) { if (_belle_sip_object_marshal_check_enabled == TRUE) return checked_marshal(vptr,obj,buff,buff_size,offset); else return vptr->marshal(obj,buff,buff_size,offset); } else { vptr=vptr->get_parent(); } } return BELLE_SIP_NOT_IMPLEMENTED; /*no implementation found*/ }1
2
3
4
5
6
7
8
9
10
11
12
13
14
[/code]
setDisplayName函数分析
Java_org_linphone_core_LinphoneAddressImpl_setDisplayName
extern "C" void Java_org_linphone_core_LinphoneAddressImpl_setDisplayName(JNIEnv* env ,jobject thiz ,jlong address ,jstring jdisplayName) { const char* displayName = jdisplayName!= NULL?env->GetStringUTFChars(jdisplayName, NULL):NULL; linphone_address_set_display_name((LinphoneAddress*)address,displayName); if (displayName != NULL) env->ReleaseStringUTFChars(jdisplayName, displayName); }1
2
3
4
5
6
7
8
[/code]
linphone_address_set_display_name
submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC int linphone_address_set_display_name(LinphoneAddress *u, const char *display_name); submodules/linphone/coreapi/address.c:int linphone_address_set_display_name(LinphoneAddress *u, const char *display_name){1
2
3
4
[/code]
/** * Sets the display name. **/ int linphone_address_set_display_name(LinphoneAddress *u, const char *display_name){ sal_address_set_display_name(u,display_name); return 0; }1
2
3
4
5
6
7
[/code]
sal_address_set_display_name
submodules/linphone/include/sal/sal.h:void sal_address_set_display_name(SalAddress *addr, const char *display_name); submodules/linphone/coreapi/bellesip_sal/sal_address_impl.c:void sal_address_set_display_name(SalAddress *addr, const char *display_name){1
2
3
[/code]
void sal_address_set_display_name(SalAddress *addr, const char *display_name){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_header_address_set_displayname(header_addr,display_name); }1
2
3
4
[/code]
belle_sip_header_address_set_displayname
submodules/belle-sip/include/belle-sip/headers.h:BELLESIP_EXPORT void belle_sip_header_address_set_displayname(belle_sip_header_address_t* address, const char* uri);1
[/code]
setDomain函数分析
Java_org_linphone_core_LinphoneAddressImpl_setDomain
extern "C" void Java_org_linphone_core_LinphoneAddressImpl_setDomain(JNIEnv* env ,jobject thiz ,jlong address ,jstring jdomain) { const char* domain = jdomain!= NULL?env->GetStringUTFChars(jdomain, NULL):NULL; linphone_address_set_domain((LinphoneAddress*)address,domain); if (domain != NULL) env->ReleaseStringUTFChars(jdomain, domain); }1
2
3
4
5
6
7
8
[/code]
linphone_address_set_domain
submodules/linphone/coreapi/address.c:int linphone_address_set_domain(LinphoneAddress *uri, const char *host){ submodules/linphone/coreapi/linphonecore.h:LINPHONE_PUBLIC int linphone_address_set_domain(LinphoneAddress *uri, const char *host);1
2
3
[/code]
/** * Sets the domain. **/ int linphone_address_set_domain(LinphoneAddress *uri, const char *host){ if (host) { char *identity = ms_strdup_printf("sip:%s", host); LinphoneAddress* test = linphone_address_new(identity); ms_free(identity); if (test) { sal_address_set_domain(uri,host); linphone_address_destroy(test); return 0; } } return -1; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[/code]
setUserName函数分析
Java_org_linphone_core_LinphoneAddressImpl_setUserName
extern "C" void Java_org_linphone_core_LinphoneAddressImpl_setUserName(JNIEnv* env ,jobject thiz ,jlong address ,jstring juserName) { const char* userName = juserName!= NULL?env->GetStringUTFChars(juserName, NULL):NULL; linphone_address_set_username((LinphoneAddress*)address,userName); if (userName != NULL) env->ReleaseStringUTFChars(juserName, userName); }1
2
3
4
5
6
7
8
[/code]
setTransport函数分析
Java_org_linphone_core_LinphoneAddressImpl_setTransport
extern "C" void Java_org_linphone_core_LinphoneAddressImpl_setTransport(JNIEnv* env ,jobject thiz ,jlong address ,jint jtransport) { linphone_address_set_transport((LinphoneAddress*)address, (LinphoneTransportType) jtransport); }1
2
3
4
5
6
[/code]
setPort函数分析
Java_org_linphone_core_LinphoneAddressImpl_setPort
extern "C" void Java_org_linphone_core_LinphoneAddressImpl_setPort(JNIEnv* env ,jobject thiz ,jlong address ,jint jport) { linphone_address_set_port((LinphoneAddress*)address, (LinphoneTransportType) jport); }1
2
3
4
5
6
[/code]
toString函数分析
Java_org_linphone_core_LinphoneAddressImpl_toString
extern "C" jstring Java_org_linphone_core_LinphoneAddressImpl_toString(JNIEnv* env ,jobject thiz ,jlong ptr) { char* uri = linphone_address_as_string((LinphoneAddress*)ptr); jstring juri =env->NewStringUTF(uri); ms_free(uri); return juri; }
相关文章推荐
- linphone-LinphoneAddressImpl文件对应的JNI层文件分析
- linphone-PresenceServiceImpl文件对应的JNI层文件分析
- linphone-PresenceActivityImpl文件对应的JNI层文件分析
- linphone-LinphoneFriendImpl文件对应的JNI层文件分析
- linphone-LinphoneChatMessageImpl文件对应的JNI层文件分析
- linphone-LpConfigImpl文件对应的JNI层文件分析
- linphone-LinphoneInfoMessageImpl文件对应的JNI层文件分析
- linphone-LinphoneProxyConfigImpl文件对应的JNI层文件分析
- linphone-ErrorInfoImpl文件对应的JNI层文件分析
- linphone-PayloadTypeImpl文件对应的JNI层文件分析
- linphone-LinphoneCoreFactoryImpl文件对应的JNI层文件分析
- linphone-LinphoneChatRoomImpl文件对应的JNI层文件分析
- linphone-PresencePersonImpl文件对应的JNI层文件分析
- linphone-PresenceNoteImpl文件对应的JNI层文件分析
- linphone-LinphoneEventImpl文件对应的JNI层文件分析
- linphone-LinphoneCallLogImpl文件对应的JNI层文件分析
- linphone-LinphoneCallParamsImpl文件对应的JNI层文件分析
- linphone-TunnelConfigImpl文件对应的JNI层文件分析
- linphone-PresenceModelImpl文件对应的JNI层文件分析
- linphone-LinphoneAddress.java文件分析