I am writing an application on Ubuntu 16.04 with PJSUA/PJSIP.I need to detect when a call is hanged-up. Is there a sort off call_state() function ?
Thank you !
Found the solution here and here :
You have to modify the static void on_call_state(pjsua_call_id call_id, pjsip_event *e) function like so :
/* Callback called by the library when call's state has changed */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(e);
pjsua_call_get_info(call_id, &ci);
PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
(int)ci.state_text.slen,
ci.state_text.ptr));
if (ci.state == PJSIP_INV_STATE_DISCONNECTED) {
/*YOUR CODE HERE*/
}
}
Related
Let's say we have a C function funA in a library, inside funA it'll call some other functions funB, funC, .etc. It's possible that funB and funC could call funA back. So the question is:
Is it possible to detect this situation just inside funA, something like:
void funA(void) {
if (...) {
// Calling back to funA
}
}
Conclusion
In a single thread environment, static/global variable would work.
In multi-thread environment, would have to depend on TLS support.
Haven't got any answer that can achieve this with just language(C) level tricks
This can be done with a static flag.
When the function is called, if the flag is not set then set it and continue, otherwise return right away. Then at the end of the function, you clear the flag so you can enter it again.
void funcA(void)
{
static int callback = 0;
if (callback) return;
callback = 1;
...
callback = 0;
}
If this needs to work in multiple thread separately you can declare the variable as _Thread_local instead of static.
If it is a single call only, you can have a global/static flag set once this function is called, and check it in the beginning. Or to remove the restriction of being single call, you can reset this flag before the function is returning.
Something like that:
void funA(void) {
static bool used = false;
if (used)
{
printf("It is used!\n");
}
used = true;
// .... Do stuff here, including possible recursion
used = false;
}
Note - this won't work with multithreading - this function is not reentrant..
maybe another approach you can identify the caller:
void func_a(void *ptr);
void func_b(void);
void func_c(void);
void func_a(void *caller)
{
if(caller == func_a)
{
printf("called from func_a\n");
return;
}
if(caller == func_b)
{
printf("called from func_b\n");
return;
}
if(caller == func_c)
{
printf("called from func_c\n");
return;
}
if(caller == NULL)
{
printf("called from somewhere elese - going to call myself\n");
func_a(func_a);
}
}
void func_b()
{
func_a(func_b);
}
void func_c()
{
func_a(func_c);
}
int main()
{
func_b();
func_c();
func_a(NULL);
return 0;
}
With a level of indirection, you can even count the number of times your function has been called:
void func( int count )
{
printf( "Count is %d\n", count );
if ( ... ) // no longer want to recurse...
{
return;
}
func( count + 1 );
}
// wrap the actual recursive call to hide the parameter
void funA()
{
func( 0 );
}
This way, it's fully thread-safe. If you don't want a wrapper function nor a parameter passed, you can use thread-specific storage.
Device : F28335 contorolCRAD and Experimenter's Kit - Delfino F28335.
Ported ucos-II.
I use OSTimeGet() function to get OSTime.
But task1 returns '0' everytime and task2 doesn't work.
What is the problem?
How to fix this?
App_Task1's priority = 6u
App_Task2's priority = 7u
static void App_Task1 (void *p_arg)
{
(void)&p_arg;
INT32U t;
while (DEF_TRUE) {
t = OSTimeGet();
printf("Task1 \n");
printf("OSTime=%lu\n",t);
OSTimeDly(5);
}
}
static void App_Task2 (void *p_arg)
{
(void)&p_arg;
INT32U t;
while (DEF_TRUE) {
t = OSTimeGet();
printf("Task2 \n");
printf("OSTime=%lu\n",t);
OSTimeDly(10);
}
}
output
Task1 OSTime=0
It seems that your Systick function isn't running correctly. As I have no experience in the Chip you are using I cannot give you the full answer.
But your systick function should contain something like this.
This is code from a LPC17xx but something similliar should happen for you
void OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-II that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-II that we are leaving the ISR */
}
The OSTimeTick() is used for your OSTimeDly(), OSTimeGet() and the task switching
I want to register event using callback i.e. function pointer in C
typedef void (*event_cb_t)(const struct event *evt, void *userdata);
enum evt{
EVENT_WRITE=0
,EVENT_READ,
EVENT_CLOSE
};
struct event_cb {
event_cb_t cb;
void *data;
};
static void my_event_cb(int event, void *data)
{
if(event ==EVENT_CLOSE)
//some code
if (event == EVENT_READ)
// some code
}
int event_cb_register(event_cb_t cb, void *userdata){
printf("hi");
return 0;
}
int main()
{
struct event_cb *callback;
callback->data=NULL;
event_cb_register(my_event_cb, NULL);
return 0;
}
I want to know when argument 1 of event_cb_register will be called?
Means as soon as event_cb_register is called or after when event_cb_register finished its functioning?
As your code stands, my_event_cb is never called. The address of it is passed to event_cb_register but that does nothing with the pointer.
my_every_cb should be copying the pointer into a variable which is of type struct event_cb. Later code can use that variable to call my_event_cb when appropriate.
I have followed the advice at
registering java function as a callback in C function and can callback with "simple" types such as integer and string, e.g.:
jstring js = (*env)->NewStringUTF(env, "hello");
(*env)->CallStaticVoidMethod(env, cls, methodid, js);
However, if I am trying to do the same with C datatypes which have been wrapped with SWIG, I am only getting null pointers in Java. In the C part they are definitely not 0. Do they need to be treated differently?
[EDIT:]
Some more information:
As stated above, char*/string is working for me as well. I am looking for a solution for C struct's, which have been wrapped by SWIG and have been allocated in Java.
E.g.:
typedef struct {
unsigned short length;
unsigned short value;
} lv_t;
is getting wrapped by SWIG, so I can use it in Java:
lv_t lv;
lv = modulename.modulename_new_lv();
lv.setLength(1);
lv.setValue(2);
Then I will give this struct from Java to C:
modulename.send(lv);
C will send it over the network, receive some reply and change the values in lv. Now, this should give the modified lv back to Java.
void jni_call_received_hook(lv_t* lv){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Lcom/something/modulename/jni/lv_t;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
// what to do here to create a jobject?
jobject lv_j = ...;
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, lv_j);
}
Which calls:
public static void messageHandler(lv_t lv) {
System.out.println("messageHandler().");
System.out.println("lv " + lv);
}
Sorry but I'm not able to comment in your question yet, so this is more a comment rather than an answer. Anyway, I've recently done something like that.
My callback works and is implemented as:
void jni_call_received_hook(char* username){
JNIEnv* m_env;
(*m_vm)->AttachCurrentThread(m_vm, (void**) &m_env, NULL );
jclass cls = (*m_env)->FindClass( m_env, "gui/StateMachine" );
jmethodID mid = (*m_env)->GetStaticMethodID(m_env, cls, "callReceivedEvent", "(Ljava/lang/String;)V");
if (mid == 0){
log(E, "Unable to find method for callback");
return;
}
(*m_env)->CallStaticVoidMethod(m_env, cls, mid, (*m_env)->NewStringUTF(m_env, username));
}
The variable m_vm is an instance of the JVM I've kept upon calling a method that registered this callback, like this:
JNIEXPORT void JNICALL Java_gui_StateMachine_setCallReceivedCallback(JNIEnv *e, jobject o){
(*e)->GetJavaVM(e, &m_vm );
set_call_received_hook(jni_call_received_hook);
}
Maybe your missing something. Let me know if this isn't clear enough. Hope it helps.
I am a newbie to C. I am trying to implement callback function using function pointers.
I am getting an error
:test_callback.c:10: error: expected identifier or ‘(’ before ‘void’
when I try to compile the following program:
#include<stdio.h>
void (*callback) (void);
void callback_proc ()
{
printf ("Inside callback function\n");
}
void register ((void (*callback) (void)))
{
printf ("Inside registration \n");
callback (); /* Calling an initial callback with function pointer */
}
int main ()
{
callback = callback_proc;/* Assigning function to the function pointer */
register (callback);/* Passing the function pointer */
return 0;
}
What is this error?Can anyone help?
register is a C keyword: Use another name for the function.
You have extra parantheses around the callback parameter. It should be:
void funcName(void (*callback) (void))
I would recommend to use a typedef
#include<stdio.h>
typedef void (*callback_t) (void);
callback_t callback;
void callback_proc(void)
{
printf ("Inside callback function\n");
}
void reg( callback_t _callback )
{
printf ("Inside registration \n");
_callback();
}
int main ()
{
callback = callback_proc;
reg(callback);
return 0;
}
EDIT: removed the register issue
You can't use 'register' as a function name as it's a C keyword.
2 problems:
you can't use the name register as it's a keyword (not used often anymore, but it's still there)
change the definition of the function from
void wasRegister((void (*callback) (void)))
to:
void wasRegister(void (*callback) (void))
(get rid of the parens around the parameter's declaration.
Also you might get a warning about callback_proc() not having a matching delaration to the callback variable (depending on how you compile the program - as C or C++), so you might want to change its declaration to:
void callback_proc (void)
to make it explicit that it takes no parameters.
Have a look at type safe callbacks from ccan. Its one thing to expose a typed function pointer for the world to use, its another to ensure sane casting.
#include<stdio.h>
typedef void (*callback_func) (void);
static callback_func the_callback = 0;
void process (void)
{
printf ("Inside process function\n");
}
void callback_register (callback_func cb)
{
the_callback = cb;
printf ("Inside registration \n");
}
void callback(void)
{
the_callback();
}
int main (void)
{
callback_register(process); /* Passing the function pointer */
callback();
return 0;
}
Declaring the_callback static would make more sense if this code was modularized and then you would be forced to call callback_register in order to set it, and callback in order to call it - the_callback would not be accessible outside of the implementation (.c) only the function declarations would be in the header (.h).