/* * Convert IPv4/IPv6 address to text. */ PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src, char *dst, int size) { PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL); *dst = '\0'; if (af==PJ_AF_INET) { TBuf<PJ_INET_ADDRSTRLEN> str16; pj_in_addr inaddr; if (size < PJ_INET_ADDRSTRLEN) return PJ_ETOOSMALL; pj_memcpy(&inaddr, src, 4); /* Symbian IP address is in host byte order */ TInetAddr temp_addr((TUint32)pj_ntohl(inaddr.s_addr), (TUint)0); temp_addr.Output(str16); pj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(), dst, size); return PJ_SUCCESS; } else if (af==PJ_AF_INET6) { TBuf<PJ_INET6_ADDRSTRLEN> str16; if (size < PJ_INET6_ADDRSTRLEN) return PJ_ETOOSMALL; TIp6Addr ip6; pj_memcpy(ip6.u.iAddr8, src, 16); TInetAddr temp_addr(ip6, (TUint)0); temp_addr.Output(str16); pj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(), dst, size); return PJ_SUCCESS; } else { pj_assert(!"Unsupport address family"); return PJ_EINVAL; } }
/* * Convert an Internet host address given in network byte order * to string in standard numbers and dots notation. */ PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr) { static char str8[PJ_INET_ADDRSTRLEN]; TBuf<PJ_INET_ADDRSTRLEN> str16(0); /* (Symbian IP address is in host byte order) */ TInetAddr temp_addr((TUint32)pj_ntohl(inaddr.s_addr), (TUint)0); temp_addr.Output(str16); return pj_unicode_to_ansi((const wchar_t*)str16.PtrZ(), str16.Length(), str8, sizeof(str8)); }
/* * Get hostname. */ PJ_DEF(const pj_str_t*) pj_gethostname(void) { static char buf[PJ_MAX_HOSTNAME]; static pj_str_t hostname; PJ_CHECK_STACK(); if (hostname.ptr == NULL) { RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(PJ_AF_INET); TRequestStatus reqStatus; THostName tmpName; resv.GetHostName(tmpName, reqStatus); User::WaitForRequest(reqStatus); hostname.ptr = pj_unicode_to_ansi((const wchar_t*)tmpName.Ptr(), tmpName.Length(), buf, sizeof(buf)); hostname.slen = tmpName.Length(); } return &hostname; }
/* * Convert IPv4/IPv6 address to text. */ PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src, char *dst, int size) { PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL); *dst = '\0'; PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP); #if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0 /* * Implementation using inet_ntop() */ if (inet_ntop(af, src, dst, size) == NULL) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) /* * Implementation on Windows, using WSAAddressToString(). * Should also work on Unicode systems. */ { PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) pj_sockaddr sock_addr; DWORD addr_len, addr_str_len; int rc; pj_bzero(&sock_addr, sizeof(sock_addr)); sock_addr.addr.sa_family = (pj_uint16_t)af; if (af == PJ_AF_INET) { if (size < PJ_INET_ADDRSTRLEN) return PJ_ETOOSMALL; pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4); addr_len = sizeof(pj_sockaddr_in); addr_str_len = PJ_INET_ADDRSTRLEN; } else if (af == PJ_AF_INET6) { if (size < PJ_INET6_ADDRSTRLEN) return PJ_ETOOSMALL; pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16); addr_len = sizeof(pj_sockaddr_in6); addr_str_len = PJ_INET6_ADDRSTRLEN; } else { pj_assert(!"Unsupported address family"); return PJ_EAFNOTSUP; } #if PJ_NATIVE_STRING_IS_UNICODE rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, NULL, wtempaddr, &addr_str_len); if (rc == 0) { pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size); } #else rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, NULL, dst, &addr_str_len); #endif if (rc != 0) { pj_status_t status = pj_get_netos_error(); if (status == PJ_SUCCESS) status = PJ_EUNKNOWN; return status; } return PJ_SUCCESS; } #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 /* IPv6 support is disabled, just return error without raising assertion */ return PJ_EIPV6NOTSUP; #else pj_assert(!"Not supported"); return PJ_EIPV6NOTSUP; #endif }
/* * pjmedia_audiodev_strerror() */ PJ_DEF(pj_str_t) pjmedia_audiodev_strerror(pj_status_t statcode, char *buf, pj_size_t bufsize ) { pj_str_t errstr; #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0) /* See if the error comes from Core Audio. */ #if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO if (statcode >= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START && statcode <= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_END) { int ca_err = PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START - statcode; PJ_UNUSED_ARG(ca_err); // TODO: create more helpful error messages errstr.ptr = buf; pj_strcpy2(&errstr, "Core audio error"); return errstr; } else #endif /* See if the error comes from PortAudio. */ #if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO if (statcode >= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START && statcode <= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END) { //int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0); int pa_err = PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START - statcode; pj_str_t msg; msg.ptr = (char*)Pa_GetErrorText(pa_err); msg.slen = pj_ansi_strlen(msg.ptr); errstr.ptr = buf; pj_strncpy_with_null(&errstr, &msg, bufsize); return errstr; } else #endif /* PJMEDIA_SOUND_IMPLEMENTATION */ /* See if the error comes from WMME */ #if PJMEDIA_AUDIO_DEV_HAS_WMME if ((statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START && statcode < PJMEDIA_AUDIODEV_WMME_IN_ERROR_END) || (statcode >= PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START && statcode < PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END)) { MMRESULT native_err, mr; MMRESULT (WINAPI *waveGetErrText)(UINT mmrError, LPTSTR pszText, UINT cchText); PJ_DECL_UNICODE_TEMP_BUF(wbuf, 80) if (statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START && statcode <= PJMEDIA_AUDIODEV_WMME_IN_ERROR_END) { native_err = statcode - PJMEDIA_AUDIODEV_WMME_IN_ERROR_START; waveGetErrText = &waveInGetErrorText; } else { native_err = statcode - PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START; waveGetErrText = &waveOutGetErrorText; } #if PJ_NATIVE_STRING_IS_UNICODE mr = (*waveGetErrText)(native_err, wbuf, PJ_ARRAY_SIZE(wbuf)); if (mr == MMSYSERR_NOERROR) { int len = wcslen(wbuf); pj_unicode_to_ansi(wbuf, len, buf, bufsize); } #else mr = (*waveGetErrText)(native_err, buf, (UINT)bufsize); #endif if (mr==MMSYSERR_NOERROR) { errstr.ptr = buf; errstr.slen = pj_ansi_strlen(buf); return errstr; } else { pj_ansi_snprintf(buf, bufsize, "MMSYSTEM native error %d", native_err); return pj_str(buf); } } else
static LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (message) { case WM_KEYUP: if (wParam==114) { wParam = ID_MENU_CALL; } else if (wParam==115) { if (g_current_call == PJSUA_INVALID_ID) wParam = ID_EXIT; else wParam = ID_MENU_DISCONNECT; } else break; case WM_COMMAND: wmId = LOWORD (wParam); wmEvent = HIWORD (wParam); if (wmId == ID_BTN_ACTION) wmId = g_current_action; switch (wmId) { case ID_MENU_CALL: if (g_current_call != PJSUA_INVALID_ID) { MessageBox (NULL, TEXT ("Can not make call"), TEXT ("You already have one call active"), MB_OK); } pj_str_t dst_uri; wchar_t text[256]; char tmp[256]; pj_status_t status; GetWindowText (hwndURI, text, PJ_ARRAY_SIZE (text)); pj_unicode_to_ansi (text, pj_unicode_strlen (text), tmp, sizeof (tmp)); dst_uri.ptr = tmp; dst_uri.slen = pj_ansi_strlen (tmp); status = pjsua_call_make_call (g_current_acc, &dst_uri, 0, NULL, NULL, &g_current_call); if (status != PJ_SUCCESS) OnError (TEXT ("Unable to make call"), status); break; case ID_MENU_ANSWER: if (g_current_call == PJSUA_INVALID_ID) MessageBox (NULL, TEXT ("Can not answer"), TEXT ("There is no call!"), MB_OK); else pjsua_call_answer (g_current_call, 200, NULL, NULL); break; case ID_MENU_DISCONNECT: if (g_current_call == PJSUA_INVALID_ID) MessageBox (NULL, TEXT ("Can not disconnect"), TEXT ("There is no call!"), MB_OK); else pjsua_call_hangup (g_current_call, PJSIP_SC_DECLINE, NULL, NULL); break; case ID_EXIT: DestroyWindow (hWnd); break; default: return DefWindowProc (hWnd, message, wParam, lParam); } break; case WM_CREATE: OnCreate (hWnd); break; case WM_DESTROY: OnDestroy(); CommandBar_Destroy (hwndCB); PostQuitMessage (0); break; case WM_TIMER: pjsua_handle_events (1); break; default: return DefWindowProc (hWnd, message, wParam, lParam); } return 0; }
/* * platform_strerror() * * Platform specific error message. This file is called by pj_strerror() * in errno.c */ int platform_strerror( pj_os_err_type os_errcode, char *buf, pj_size_t bufsize) { pj_size_t len = 0; PJ_DECL_UNICODE_TEMP_BUF(wbuf,128); pj_assert(buf != NULL); pj_assert(bufsize >= 0); /* * MUST NOT check stack here. * This function might be called from PJ_CHECK_STACK() itself! //PJ_CHECK_STACK(); */ if (!len) { #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING!=0) int i; for (i = 0; gaErrorList[i].msg; ++i) { if (gaErrorList[i].code == os_errcode) { len = strlen(gaErrorList[i].msg); if ((pj_size_t)len >= bufsize) { len = bufsize-1; } pj_memcpy(buf, gaErrorList[i].msg, len); buf[len] = '\0'; break; } } #endif /* PJ_HAS_ERROR_STRING */ } if (!len) { #if PJ_NATIVE_STRING_IS_UNICODE len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wbuf, sizeof(wbuf), NULL); if (len) { pj_unicode_to_ansi(wbuf, len, buf, bufsize); } #else len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, os_errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (int)bufsize, NULL); buf[bufsize-1] = '\0'; #endif if (len) { /* Remove trailing newlines. */ while (len && (buf[len-1] == '\n' || buf[len-1] == '\r')) { buf[len-1] = '\0'; --len; } } } if (!len) { len = pj_ansi_snprintf( buf, bufsize, "Win32 error code %u", (unsigned)os_errcode); if (len < 0 || len >= (int)bufsize) len = bufsize-1; buf[len] = '\0'; } return (int)len; }
// Resolve for specific address family static pj_status_t getaddrinfo_by_af(int af, const pj_str_t *name, unsigned *count, pj_addrinfo ai[]) { unsigned i; pj_status_t status; PJ_ASSERT_RETURN(name && count && ai, PJ_EINVAL); #if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6 if (af == PJ_AF_INET6) return PJ_EIPV6NOTSUP; #endif // Return failure if access point is marked as down by app. PJ_SYMBIAN_CHECK_CONNECTION(); // Get resolver for the specified address family RHostResolver &resv = PjSymbianOS::Instance()->GetResolver(af); // Convert name to Unicode wchar_t name16[PJ_MAX_HOSTNAME]; pj_ansi_to_unicode(name->ptr, name->slen, name16, PJ_ARRAY_SIZE(name16)); TPtrC16 data((const TUint16*)name16); // Resolve! TNameEntry nameEntry; TRequestStatus reqStatus; resv.GetByName(data, nameEntry, reqStatus); User::WaitForRequest(reqStatus); // Iterate each result i = 0; while (reqStatus == KErrNone && i < *count) { // Get the resolved TInetAddr TInetAddr inetAddr(nameEntry().iAddr); int addrlen; #if TRACE_ME if (1) { pj_sockaddr a; char ipaddr[PJ_INET6_ADDRSTRLEN+2]; int namelen; namelen = sizeof(pj_sockaddr); if (PjSymbianOS::Addr2pj(inetAddr, a, &namelen, PJ_FALSE) == PJ_SUCCESS) { PJ_LOG(5,(THIS_FILE, "resolve %.*s: %s", (int)name->slen, name->ptr, pj_sockaddr_print(&a, ipaddr, sizeof(ipaddr), 2))); } } #endif // Ignore if this is not the same address family // Not a good idea, as Symbian mapps IPv4 to IPv6. //fam = inetAddr.Family(); //if (fam != af) { // resv.Next(nameEntry, reqStatus); // User::WaitForRequest(reqStatus); // continue; //} // Convert IP address first to get IPv4 mapped address addrlen = sizeof(ai[i].ai_addr); status = PjSymbianOS::Addr2pj(inetAddr, ai[i].ai_addr, &addrlen, PJ_TRUE); if (status != PJ_SUCCESS) return status; // Ignore if address family doesn't match if (ai[i].ai_addr.addr.sa_family != af) { resv.Next(nameEntry, reqStatus); User::WaitForRequest(reqStatus); continue; } // Convert the official address to ANSI. pj_unicode_to_ansi((const wchar_t*)nameEntry().iName.Ptr(), nameEntry().iName.Length(), ai[i].ai_canonname, sizeof(ai[i].ai_canonname)); // Next ++i; resv.Next(nameEntry, reqStatus); User::WaitForRequest(reqStatus); } *count = i; return PJ_SUCCESS; }