/** * Answer an incoming call * * @param ua User-Agent * @param call Call to hangup, or NULL for current call * * @return 0 if success, otherwise errorcode */ int ua_answer(struct ua *ua, struct call *call) { if (!ua) return EINVAL; if (!call) { call = ua_call(ua); if (!call) return ENOENT; } /* todo: put previous call on-hold (if configured) */ ua->play = mem_deref(ua->play); return call_answer(call, 200); }
static void call_event_handler(struct call *call, enum call_event ev, const char *str, void *arg) { struct ua *ua = arg; const char *peeruri; struct call *call2 = NULL; int err; MAGIC_CHECK(ua); peeruri = call_peeruri(call); /* stop any ringtones */ ua->play = mem_deref(ua->play); switch (ev) { case CALL_EVENT_INCOMING: if (contact_block_access(peeruri)) { info("ua: blocked access: \"%s\"\n", peeruri); ua_event(ua, UA_EVENT_CALL_CLOSED, call, str); mem_deref(call); break; } switch (ua->acc->answermode) { case ANSWERMODE_EARLY: (void)call_progress(call); break; case ANSWERMODE_AUTO: (void)call_answer(call, 200); break; case ANSWERMODE_MANUAL: default: if (list_count(&ua->calls) > 1) { (void)play_file(&ua->play, "callwaiting.wav", 3); } else { /* Alert user */ (void)play_file(&ua->play, "ring.wav", -1); } ua_event(ua, UA_EVENT_CALL_INCOMING, call, peeruri); break; } break; case CALL_EVENT_RINGING: (void)play_file(&ua->play, "ringback.wav", -1); ua_event(ua, UA_EVENT_CALL_RINGING, call, peeruri); break; case CALL_EVENT_PROGRESS: ua_printf(ua, "Call in-progress: %s\n", peeruri); ua_event(ua, UA_EVENT_CALL_PROGRESS, call, peeruri); break; case CALL_EVENT_ESTABLISHED: ua_printf(ua, "Call established: %s\n", peeruri); ua_event(ua, UA_EVENT_CALL_ESTABLISHED, call, peeruri); break; case CALL_EVENT_CLOSED: if (call_scode(call)) { const char *tone; tone = translate_errorcode(call_scode(call)); if (tone) (void)play_file(&ua->play, tone, 1); } ua_event(ua, UA_EVENT_CALL_CLOSED, call, str); mem_deref(call); break; case CALL_EVENT_TRANSFER: /* * Create a new call to transfer target. * * NOTE: we will automatically connect a new call to the * transfer target */ ua_printf(ua, "transferring call to %s\n", str); err = ua_call_alloc(&call2, ua, VIDMODE_ON, NULL, call, call_localuri(call)); if (!err) { struct pl pl; pl_set_str(&pl, str); err = call_connect(call2, &pl); if (err) { warning("ua: transfer: connect error: %m\n", err); } } if (err) { (void)call_notify_sipfrag(call, 500, "Call Error"); mem_deref(call2); } break; case CALL_EVENT_TRANSFER_FAILED: ua_event(ua, UA_EVENT_CALL_TRANSFER_FAILED, call, str); break; } }
//2 <sparam>=<call_id>, <lparam>=<t_CSessionID> error_t call_WndMsgHandler(t_HWindow handle, t_WidgetEvent evt, t_sparam sparam, t_lparam lparam) { error_t ret = NOT_HANDLED; t_CallWindowData *wdata = (t_CallWindowData*)wgt_get_tag(handle); switch(evt){ case WINDOW_OnOpen: g_printf("WINDOW_OnOpen\r\n"); { t_HWidget widget; wgt_enable_attr(handle, WND_ATTR_HAS_STATUS|WND_ATTR_HAS_TITLE); wdata = MALLOC(sizeof(t_CallWindowData)); memset(wdata, 0, sizeof(t_CallWindowData)); wdata->cid = sparam; wdata->contact = lparam; wdata->info = call_get_info(wdata->cid); wdata->number = wdata->info->phone; if(wdata->contact == CSESSION_NULL){ wdata->contact = contact_query_by_number(wdata->number, wdata->name, sizeof(wdata->name)); } wdata->cinfo = contact_get_info(wdata->contact); if(wdata->cinfo) wdata->name = wdata->cinfo->name; else wdata->name = wdata->number; wdata->timer = -1; datetime_current(&wdata->dt); wdata->tick = tick_current(); wdata->connected = FALSE; wdata->handfree = FALSE; wdata->mute = FALSE; wdata->held = FALSE; wdata->keypad = FALSE; wdata->btn_down = -1; dev_audio_set_path(wdata->info->aud, AUD_DEV_RECEIVER); wgt_set_tag(handle, wdata); call_StartTimer(handle); //wnd_SetTitle(handle, "Outgoing Call", BRD_HANDLE_SELF, RESID_STR_OUTGOING); #if 0 widget = wnd_get_widget(handle, RESID_LABEL_NUMBER); if(g_object_valid(widget)){ label_set_text(widget, wdata->name); } widget = wnd_get_widget(handle, RESID_LABEL_EVENT); if(g_object_valid(widget)){ if(wdata->info->outgoing) wgt_set_caption_by_resid(widget, brd_get(PACK_GUID_SELF), gaCallEvtResid[CALL_EVT_O_ALERT]); else wgt_set_caption_by_resid(widget, brd_get(PACK_GUID_SELF), gaCallEvtResid[CALL_EVT_INCOMING]); label_set_text(widget, ""); } widget = wnd_get_widget(handle, RESID_CTRL_IMAGE); if(g_object_valid(widget)){ t_ContactInfo info; if(!IS_UNSAVED_CONTACT(wdata->contact) && wdata->contact != UNKNOWN_CONTACT && contact_get_info(wdata->contact, &info)){ if(info.pic_resid) imagectrl_set_by_resid(widget, brd_get("contact"), info.pic_resid); else if(info.pic_fname) imagectrl_set_by_file(widget, info.pic_fname); else imagectrl_set_by_resid(widget, brd_get(PACK_GUID_SELF), RESID_IMG_PICTURE); contact_free_info(&info); }else{ imagectrl_set_by_resid(widget, brd_get(PACK_GUID_SELF), RESID_IMG_PICTURE); } wgt_disable_attr(widget, CTRL_ATTR_TABSTOP); } #endif if(wgt_get_resid(handle) == RESID_WIN_CALL){ widget = wnd_get_widget(handle, RESID_BTN_END); wgt_set_text_align(widget, guiRight); wgt_set_border(widget, BORDER_TYPE_3DIN, 1, guiFourCorner); wgt_set_bg_fill(widget, GDI_FILL_MODE_2COLOR_H, MAKE_RGB(0xe0,0,0), MAKE_RGB(0xb0,0,0)); widget = wnd_get_widget(handle, RESID_BTN_HIDE_KEYPAD); wgt_set_text_align(widget, guiRight); wgt_set_border(widget, BORDER_TYPE_3DIN, 2, guiFourCorner); wgt_set_bg_fill(widget, GDI_FILL_MODE_2COLOR_H, MAKE_RGB(0xe0,0,0), MAKE_RGB(0xb0,0,0)); }else if(wgt_get_resid(handle) == RESID_WIN_CALL_MT){ wgt_set_text_align(wnd_get_widget(handle, RESID_BTN_ANSWER), guiRight); wgt_set_text_align(wnd_get_widget(handle, RESID_BTN_END_MO), guiRight); } sk_set_text(wnd_get_skbar(handle), SK_LSK, NULL, RESID_STR_CALL_KEYPAD); sk_set_text(wnd_get_skbar(handle), SK_RSK, NULL, RESID_STR_BACK); ret = SUCCESS; } break; case WINDOW_OnClose: g_printf("WINDOW_OnClose\r\n"); if(wdata){ if(wdata->cid >= 0) call_end(wdata->cid); if(wdata->timer >= 0) timer_release(wdata->timer); contact_free_info(wdata->cinfo); FREE(wdata); } ret = SUCCESS; break; case WIDGET_OnPreDraw: __window_predraw(handle); break; case WINDOW_OnDraw: g_printf("WINDOW_OnDraw\r\n"); //__show_incall_panel(handle, NULL, TRUE); ret = SUCCESS; break; case WIDGET_OnSelected: switch(wgt_get_resid(lparam)){ #if 0 // alvin case RESID_BTN_MUTE: if(wdata->mute){ dev_audio_mute(wdata->info->aud, FALSE); wdata->mute = FALSE; wgt_set_caption_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_STR_MUTE); wgt_set_icon_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_IMG_MUTE); }else{ dev_audio_mute(wdata->info->aud, TRUE); wdata->mute = TRUE; wgt_set_caption_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_STR_UNMUTE); wgt_set_icon_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_IMG_UNMUTE); } wgt_redraw((t_HWidget)lparam, FALSE); ret = SUCCESS; break; case RESID_BTN_SPEAKER: if(wdata->handfree){ dev_audio_set_path(wdata->info->aud, AUD_DEV_RECEIVER); dev_audio_set_volume(wdata->info->aud, VOLUME_LEVEL_6); wdata->handfree = FALSE; wgt_set_caption_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_STR_SPEAKER_ON); wgt_set_icon_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_IMG_SPEAKER_ON); }else{ dev_audio_set_path(wdata->info->aud, AUD_DEV_SPEAKER); dev_audio_set_volume(wdata->info->aud, VOLUME_LEVEL_6); wdata->handfree = TRUE; wgt_set_caption_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_STR_SPEAKER_OFF); wgt_set_icon_by_resid((t_HWidget)lparam, BRD_HANDLE_SELF, RESID_IMG_SPEAKER_OFF); } wgt_redraw((t_HWidget)lparam, FALSE); ret = SUCCESS; break; #endif case RESID_BTN_END: call_handle_end(wdata, handle); ret = SUCCESS; break; case RESID_BTN_END_MO: call_handle_end(wdata, handle); ret = SUCCESS; break; case RESID_BTN_ANSWER: call_answer(wdata->cid); ret = SUCCESS; break; case RESID_BTN_HIDE_KEYPAD: __incall_keypad_toggle(handle, wdata); break; } break; #if !defined(FTR_NO_INPUT_KEY) case WIDGET_OnKeyEvent: if(sparam != MMI_KEY_PRESS && sparam != MMI_KEY_REPEAT) break; switch(lparam){ case MVK_SEND: break; case MVK_END: call_handle_end(wdata, handle); ret = SUCCESS; break; case MVK_RSK: GOTO_DESKTOP(); ret = SUCCESS; break; case MVK_0: case MVK_1: case MVK_2: case MVK_3: case MVK_4: case MVK_5: case MVK_6: case MVK_7: case MVK_8: case MVK_9: if(wdata->info->outgoing && wdata->info->state == CALL_STATE_INCALL){ call_stop_dtmf(wdata->cid); call_send_dtmf(wdata->cid, '0'+lparam-MVK_0); label_append_char(wnd_get_widget(handle, RESID_LABEL_NUMBER), '0'+lparam-MVK_0); wgt_redraw(wnd_get_widget(handle, RESID_LABEL_NUMBER), FALSE); } break; case MVK_STAR: if(wdata->info->outgoing && wdata->info->state == CALL_STATE_INCALL){ call_stop_dtmf(wdata->cid); call_send_dtmf(wdata->cid, '*'); label_append_char(wnd_get_widget(handle, RESID_LABEL_NUMBER), '*'); wgt_redraw(wnd_get_widget(handle, RESID_LABEL_NUMBER), FALSE); } break; case MVK_HASH: if(wdata->info->outgoing && wdata->info->state == CALL_STATE_INCALL){ call_stop_dtmf(wdata->cid); call_send_dtmf(wdata->cid, '#'); label_append_char(wnd_get_widget(handle, RESID_LABEL_NUMBER), '#'); wgt_redraw(wnd_get_widget(handle, RESID_LABEL_NUMBER), FALSE); } break; } break; #endif case WIDGET_OnPenEvent: { coord_t x0,y0; PEN_XY(lparam, x0,y0); switch(PEN_TYPE(lparam)){ case MMI_PEN_DOWN: if(!wgt_point_in_client(handle, &x0, &y0)) break; __incall_OnPenEvent(handle, wdata, __get_pad_cell(wdata, x0, y0, NULL), MMI_PEN_DOWN); break; case MMI_PEN_UP: if(wdata->btn_down >= 0 && wgt_point_in_client(handle, &x0, &y0)){ __incall_OnPenEvent(handle, wdata, __get_pad_cell(wdata, x0, y0, NULL), MMI_PEN_UP); } break; case MMI_PEN_MOVE: if(wdata->btn_down >= 0){ } break; } ret = SUCCESS; } break; } return ret; }