su_open_c_localinfo.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@ingroup su_open_c_localinfo.cpp
  25. *
  26. * @CFILE su_open_c_localinfo.cpp
  27. * Functionality for choosing an access point for sockets on Symbian.
  28. *
  29. * @author Martti Mela <Martti.Mela@nokia.com>
  30. * @date Created: Fri May 18 14:31:41 2007 mela
  31. *
  32. */
  33. #include "config.h"
  34. #include <unistd.h>
  35. #include <in_sock.h>
  36. #include <es_sock.h>
  37. #include <e32base.h>
  38. #include <s32mem.h>
  39. #include <s32strm.h>
  40. #include <commdbconnpref.h>
  41. #include <sofia-sip/su.h>
  42. su_sockaddr_t sa_global[1];
  43. /* Copy IP address for the sockaddr structure.
  44. *
  45. * @param su pointer to allocated su_sockaddr_t structure
  46. *
  47. * @return 0 if successful.
  48. */
  49. extern "C" int su_get_local_ip_addr(su_sockaddr_t *su)
  50. {
  51. su->su_sin.sin_addr.s_addr = sa_global->su_sin.sin_addr.s_addr;
  52. su->su_family = sa_global->su_family;
  53. su->su_len = sa_global->su_len;
  54. return 0;
  55. }
  56. /* Set up the access point for the stack. Code adapted from Forum Nokia,
  57. * http://wiki.forum.nokia.com/index.php/LocalDeviceIpAddress.
  58. *
  59. * @param su su_sockaddr_t structure
  60. * @param ifindex pointer to interface index
  61. *
  62. * @return Connection object
  63. */
  64. extern "C" void *su_localinfo_ap_set(su_sockaddr_t *su, int *ifindex)
  65. {
  66. TCommDbConnPref iPref;
  67. RSocketServ aSocketServ;
  68. RSocket sock;
  69. /* Get the IAP id of the underlying interface of this RConnection */
  70. TUint32 iapId;
  71. iPref.SetDirection(ECommDbConnectionDirectionOutgoing);
  72. iPref.SetDialogPreference(ECommDbDialogPrefPrompt);
  73. iPref.SetBearerSet(KCommDbBearerUnknown /*PSD*/);
  74. aSocketServ = RSocketServ();
  75. aSocketServ.Connect();
  76. RConnection *aConnection = new RConnection();
  77. aConnection->Open(aSocketServ);
  78. aConnection->Start(iPref);
  79. User::LeaveIfError(sock.Open(aSocketServ, KAfInet, KSockStream,
  80. KProtocolInetTcp));
  81. User::LeaveIfError(aConnection->GetIntSetting(_L("IAP\\Id"), iapId));
  82. /* Get IP information from the socket */
  83. TSoInetInterfaceInfo ifinfo;
  84. TPckg<TSoInetInterfaceInfo> ifinfopkg(ifinfo);
  85. TSoInetIfQuery ifquery;
  86. TPckg<TSoInetIfQuery> ifquerypkg(ifquery);
  87. /* To find out which interfaces are using our current IAP, we
  88. * must enumerate and go through all of them and make a query
  89. * by name for each. */
  90. User::LeaveIfError(sock.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
  91. while(sock.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, ifinfopkg) == KErrNone) {
  92. ifquery.iName = ifinfo.iName;
  93. TInt err = sock.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifquerypkg);
  94. /* IAP ID is index 1 of iZone */
  95. if(err == KErrNone && ifquery.iZone[1] == iapId) {
  96. /* We have found an interface using the IAP we are interested in. */
  97. if(ifinfo.iAddress.Address() > 0) {
  98. /* found a IPv4 address */
  99. su->su_sin.sin_addr.s_addr = htonl(ifinfo.iAddress.Address());
  100. sa_global->su_sin.sin_addr.s_addr = su->su_sin.sin_addr.s_addr;
  101. sa_global->su_family = su->su_family = AF_INET;
  102. sa_global->su_len = su->su_len = 28;
  103. *ifindex = iapId;
  104. return (void *) aConnection;
  105. }
  106. }
  107. else if(err != KErrNone)
  108. break;
  109. }
  110. sock.Close();
  111. return (void *) aConnection;
  112. }
  113. /* Deinitialize the access point in use.
  114. *
  115. * @param aconn Pointer to connection object
  116. *
  117. * @return 0 if successful.
  118. */
  119. extern "C" int su_localinfo_ap_deinit(void *aconn)
  120. {
  121. RConnection *aConnection = (RConnection *) aconn;
  122. aConnection->Stop();
  123. aConnection->Close();
  124. delete aConnection;
  125. return 0;
  126. }