425 |
422 |
426 if (addr.iError != 0) |
423 if (addr.iError != 0) |
427 { |
424 { |
428 return addr.iError; |
425 return addr.iError; |
429 } |
426 } |
430 |
427 |
431 if (iSocketPtr == NULL) |
428 ret = maybe_reopen_socket(); |
432 { |
429 if (ret != KErrNone) |
433 ret = OpenUsingPreference(); |
430 return ret; |
434 if (ret != KErrNone) // Error in open |
431 ATOMICSOCKETOP(ret = iSocket.Bind(addr),return KErrBadHandle) |
435 { |
432 return ret; |
436 return ret; |
|
437 } |
|
438 } |
|
439 return iSocket.Bind(addr); |
|
440 } |
433 } |
441 |
434 |
442 TInt CSocketDesc::Listen(TUint qSize) |
435 TInt CSocketDesc::Listen(TUint qSize) |
443 { |
436 { |
|
437 |
|
438 TInt ret; |
444 if (iStyle == SOCK_DGRAM) // Listen on UDP socket, crashing at RSocket::Listen(). |
439 if (iStyle == SOCK_DGRAM) // Listen on UDP socket, crashing at RSocket::Listen(). |
445 { |
440 { |
446 return EOPNOTSUPP; |
441 return EOPNOTSUPP; |
447 } |
442 } |
448 if (iSocketPtr == NULL) |
443 |
449 { |
444 ret = maybe_reopen_socket(); |
450 TInt ret = OpenUsingPreference(); |
445 if (ret != KErrNone) |
451 if (ret != KErrNone) // Error in open |
446 return ret; |
452 { |
447 |
453 return ret; |
|
454 } |
|
455 } |
|
456 return CSockDescBase::Listen(qSize); |
448 return CSockDescBase::Listen(qSize); |
457 } |
449 } |
458 |
450 |
459 TInt CSocketDesc::SockName(int anEnd, struct sockaddr* anAddr,unsigned long* aSize) |
451 TInt CSocketDesc::SockName(int anEnd, struct sockaddr* anAddr,unsigned long* aSize) |
460 { |
452 { |
461 TInt ret; |
453 |
462 if (iSocketPtr == NULL) |
454 |
|
455 if (!anAddr) |
463 { |
456 { |
464 ret = OpenUsingPreference(); |
457 return EFAULT; |
465 if (ret != KErrNone) // Error in open |
|
466 { |
|
467 return ret; |
|
468 } |
|
469 } |
458 } |
|
459 |
|
460 TInt ret = maybe_reopen_socket(); |
|
461 if (ret != KErrNone) |
|
462 return ret; |
470 |
463 |
471 if ( anAddr == 0 ) // if the sockaddr passed is NULL return EFAULT. |
|
472 { |
|
473 return EFAULT; |
|
474 } |
|
475 |
|
476 |
464 |
477 struct sockaddr temp; |
465 struct sockaddr temp; |
478 unsigned long len = sizeof( temp ); |
466 unsigned long len = sizeof( temp ); |
479 |
467 |
480 TUSockAddr nSockAddr(&temp, len ); |
468 TUSockAddr nSockAddr(&temp, len ); |
501 } |
489 } |
502 if (anOption.Length() == 0) |
490 if (anOption.Length() == 0) |
503 { |
491 { |
504 return EINVAL; |
492 return EINVAL; |
505 } |
493 } |
506 if (iSocketPtr == NULL) |
494 |
507 { |
495 ret = maybe_reopen_socket(); |
508 ret = OpenUsingPreference(); |
496 if (ret != KErrNone) |
509 if (ret != KErrNone) // Error in open |
497 return ret; |
510 { |
|
511 return ret; |
|
512 } |
|
513 } |
|
514 |
498 |
515 if (SO_TYPE == anOptionName && SOL_SOCKET == anOptionLevel) |
499 if (SO_TYPE == anOptionName && SOL_SOCKET == anOptionLevel) |
516 { |
500 { |
517 TProtocolDesc protocolInfo; |
501 TProtocolDesc protocolInfo; |
518 ret = iSocket.Info(protocolInfo); |
502 ATOMICSOCKETOP(ret = iSocket.Info(protocolInfo), ret = KErrBadHandle) |
519 if (KErrNone == ret ) |
503 if (KErrNone == ret ) |
520 { |
504 { |
521 //Copy the Socket Type to the buffer |
505 // Copy the Socket Type to the buffer |
522 TInt size; |
506 TInt size = (anOption.Length() < sizeof(protocolInfo.iSockType))? anOption.Length(): sizeof(protocolInfo.iSockType); |
523 size = (anOption.Length() < sizeof(protocolInfo.iSockType))? anOption.Length(): sizeof(protocolInfo.iSockType); |
|
524 Mem::Copy((unsigned char*)anOption.Ptr(), &protocolInfo.iSockType, size); |
507 Mem::Copy((unsigned char*)anOption.Ptr(), &protocolInfo.iSockType, size); |
525 anOption.SetLength(size); |
508 anOption.SetLength(size); |
526 } |
509 } |
527 return ret; |
510 return ret; |
528 } |
511 } |
530 if(IPPROTO_IP == anOptionLevel && IP_MULTICAST_IF == anOptionName) |
513 if(IPPROTO_IP == anOptionLevel && IP_MULTICAST_IF == anOptionName) |
531 { |
514 { |
532 TUSockAddr addr; |
515 TUSockAddr addr; |
533 struct sockaddr_in sockAddress; |
516 struct sockaddr_in sockAddress; |
534 sockAddress.sin_family = AF_INET; |
517 sockAddress.sin_family = AF_INET; |
535 sockAddress.sin_port = iSocket.LocalPort(); |
518 ATOMICSOCKETOP(sockAddress.sin_port = iSocket.LocalPort(),return KErrBadHandle) |
536 iSocket.LocalName(addr); |
519 ATOMICSOCKETOP(iSocket.LocalName(addr);,return KErrBadHandle) |
537 |
|
538 TInt a = sizeof(sockAddress); |
520 TInt a = sizeof(sockAddress); |
539 addr.Get(&sockAddress,(unsigned long*)&a); |
521 addr.Get(&sockAddress,(unsigned long*)&a); |
540 TInt size; |
522 TInt size = (anOption.Length() < sizeof(sockAddress.sin_addr))? anOption.Length(): sizeof(sockAddress.sin_addr); |
541 size = (anOption.Length() < sizeof(sockAddress.sin_addr))? anOption.Length(): sizeof(sockAddress.sin_addr); |
|
542 Mem::Copy((unsigned char*)anOption.Ptr(), &(sockAddress.sin_addr), size); |
523 Mem::Copy((unsigned char*)anOption.Ptr(), &(sockAddress.sin_addr), size); |
543 anOption.SetLength(size); |
524 anOption.SetLength(size); |
544 return KErrNone; |
525 return KErrNone; |
545 } |
526 } |
546 |
|
547 |
|
548 |
527 |
549 switch(anOptionLevel) |
528 switch(anOptionLevel) |
550 { |
529 { |
551 case IPPROTO_TCP: |
530 case IPPROTO_TCP: |
552 anOptionLevel=SOL_TCP; |
531 anOptionLevel=SOL_TCP; |
596 aIndex = 0; |
575 aIndex = 0; |
597 return aIndex; |
576 return aIndex; |
598 } |
577 } |
599 else |
578 else |
600 { |
579 { |
601 TInt ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
580 TInt ret = KErrNone; |
|
581 ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle) |
602 if (ret != KErrNone) |
582 if (ret != KErrNone) |
603 return KErrGeneral; |
583 return KErrGeneral; |
604 |
584 |
605 TPckgBuf<TSoInetInterfaceInfo>iface; |
585 TPckgBuf<TSoInetInterfaceInfo>iface; |
606 while(iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface) == KErrNone) |
586 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle ) |
|
587 while(ret == KErrNone) |
607 { |
588 { |
608 TSoInetInterfaceInfo &info = iface(); |
589 TSoInetInterfaceInfo &info = iface(); |
609 TInt result; |
590 TInt result; |
610 if(info.iState == EIfUp) |
591 if(info.iState == EIfUp) |
611 { |
592 { |
612 if (anAddr == info.iAddress.Address()) |
593 if (anAddr == info.iAddress.Address()) |
613 { |
594 { |
614 ifq().iName = info.iName; |
595 ifq().iName = info.iName; |
615 result = iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifq); |
596 ATOMICSOCKETOP( result = iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifq), result = KErrBadHandle ) |
616 if (result == KErrNone) |
597 if (result == KErrNone) |
617 aIndex = ifq().iIndex; |
598 aIndex = ifq().iIndex; |
618 |
599 |
619 } |
600 } |
620 } |
601 } |
621 |
602 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle ) |
622 } |
603 } |
623 } |
604 } |
624 return aIndex; |
605 return aIndex; |
625 } |
606 } |
626 |
607 |
692 // Set the multicast addr |
669 // Set the multicast addr |
693 from = (TUint8 *)anOption.Ptr(); |
670 from = (TUint8 *)anOption.Ptr(); |
694 maddr=(from[0]<<24)+(from[1]<<16)+(from[2]<<8)+from[3]; |
671 maddr=(from[0]<<24)+(from[1]<<16)+(from[2]<<8)+from[3]; |
695 multiAddr.SetAddress( maddr); |
672 multiAddr.SetAddress( maddr); |
696 multiAddr.ConvertToV4Mapped(); |
673 multiAddr.ConvertToV4Mapped(); |
697 if(multiAddr.IsMulticast()){ |
674 if (multiAddr.IsMulticast()) |
698 req().iAddr = multiAddr.Ip6Address(); |
675 { |
699 req().iInterface = aIndex; |
676 req().iAddr = multiAddr.Ip6Address(); |
700 } |
677 req().iInterface = aIndex; |
701 return iSocket.SetOpt(anOptionName, anOptionLevel, req); |
678 } |
|
679 ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName, anOptionLevel, req), return KErrBadHandle ) |
|
680 return ret; |
702 |
681 |
703 case IP_MULTICAST_TTL: |
682 case IP_MULTICAST_TTL: |
704 anOptionLevel=KSolInetIp; |
683 anOptionLevel=KSolInetIp; |
705 anOptionName=KSoIp6MulticastHops; |
684 anOptionName=KSoIp6MulticastHops; |
706 Option = (TInt*)anOption.Ptr(); |
685 Option = (TInt*)anOption.Ptr(); |
707 ttlValue = *Option; |
686 ttlValue = *Option; |
708 return iSocket.SetOpt(anOptionName,anOptionLevel,ttlValue); |
687 ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName,anOptionLevel,ttlValue), return KErrBadHandle ) |
709 |
688 return ret; |
|
689 |
710 case SO_BROADCAST: |
690 case SO_BROADCAST: |
711 //check if user is trying to disable broadcast |
691 //check if user is trying to disable broadcast |
712 Option = (TInt*)anOption.Ptr(); |
692 Option = (TInt*)anOption.Ptr(); |
713 if (*Option == 0) |
693 return (*Option == 0 ? KErrNotSupported : KErrNone); |
714 { |
|
715 return KErrNotSupported; |
|
716 } |
|
717 else |
|
718 { |
|
719 return KErrNone; |
|
720 } |
|
721 |
694 |
722 case IP_MULTICAST_IF: |
695 case IP_MULTICAST_IF: |
723 { |
696 { |
724 //No support for equivalent flag KsoIp6MulticastIf presently |
697 //No support for equivalent flag KsoIp6MulticastIf presently |
725 //call bind instead |
698 //call bind instead |
726 struct in_addr *inAddress = (struct in_addr*)anOption.Ptr(); |
699 struct in_addr *inAddress = (struct in_addr*)anOption.Ptr(); |
727 struct sockaddr_in sockAddress; |
700 struct sockaddr_in sockAddress; |
728 sockAddress.sin_family = AF_INET; |
701 sockAddress.sin_family = AF_INET; |
729 sockAddress.sin_port = iSocket.LocalPort(); |
702 ATOMICSOCKETOP(sockAddress.sin_port = iSocket.LocalPort();,return KErrBadHandle) |
730 sockAddress.sin_addr.s_addr = inAddress->s_addr; |
703 sockAddress.sin_addr.s_addr = inAddress->s_addr; |
731 TUSockAddr ifAddress(&sockAddress, sizeof(sockAddress)); |
704 TUSockAddr ifAddress(&sockAddress, sizeof(sockAddress)); |
732 return iSocket.Bind(ifAddress); |
705 ATOMICSOCKETOP( ret = iSocket.Bind(ifAddress), return KErrBadHandle ) |
|
706 return ret; |
733 } |
707 } |
734 |
708 |
735 case IP_MULTICAST_LOOP: |
709 case IP_MULTICAST_LOOP: |
736 anOptionLevel=KSolInetIp; |
710 anOptionLevel=KSolInetIp; |
737 anOptionName=KSoIp6MulticastLoop; |
711 anOptionName=KSoIp6MulticastLoop; |
738 break; |
712 break; |
739 |
713 |
740 default: |
714 |
741 break; |
715 |
742 |
716 } |
743 } |
717 ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName,anOptionLevel,anOption), return KErrBadHandle ) |
744 return iSocket.SetOpt(anOptionName,anOptionLevel,anOption); |
718 return ret; |
745 } |
719 } |
746 |
720 |
747 void CSocketDesc::Sync (TRequestStatus& aStatus) |
721 void CSocketDesc::Sync (TRequestStatus& aStatus) |
748 { |
722 { |
749 // Judging from the Solaris man pages, this does nothing. |
723 // Judging from the Solaris man pages, this does nothing. |
750 Complete(aStatus,KErrNone); |
724 Complete(aStatus,KErrNone); |
751 } |
725 } |
752 |
726 |
753 void CSocketDesc::RecvFrom(TDes8& aDesc, TSockAddr& from, int flags, TRequestStatus& aStatus) |
727 void CSocketDesc::RecvFrom(TDes8& aDesc, TSockAddr& from, int flags, TRequestStatus& aStatus) |
754 { |
728 { |
|
729 TInt err = maybe_reopen_socket(); |
|
730 if (err != KErrNone) |
|
731 { |
|
732 Complete(aStatus, err); |
|
733 return; |
|
734 } |
|
735 |
755 iReadLock.Wait(); |
736 iReadLock.Wait(); |
756 // RSocket::Open() is postponed from socket() |
|
757 if (iSocketPtr == NULL) |
|
758 { |
|
759 TInt ret = OpenUsingPreference(); |
|
760 if (ret != KErrNone) |
|
761 { |
|
762 Complete(aStatus,ret); // Error in open |
|
763 iReadLock.Signal(); |
|
764 return; |
|
765 } |
|
766 } |
|
767 |
|
768 CSockDescBase::RecvFrom(aDesc, from, flags, aStatus); |
737 CSockDescBase::RecvFrom(aDesc, from, flags, aStatus); |
769 iReadLock.Signal(); |
738 iReadLock.Signal(); |
770 } |
739 } |
771 |
740 |
772 void CSocketDesc::RecvFromCancel() |
741 void CSocketDesc::RecvFromCancel() |
778 } |
747 } |
779 |
748 |
780 |
749 |
781 void CSocketDesc::SendTo(TDes8& aDesc, const struct sockaddr* anAddr, unsigned long aAddrLen, int flags, TRequestStatus& aStatus) |
750 void CSocketDesc::SendTo(TDes8& aDesc, const struct sockaddr* anAddr, unsigned long aAddrLen, int flags, TRequestStatus& aStatus) |
782 { |
751 { |
783 iWriteLock.Wait(); |
752 TInt err = maybe_reopen_socket(); |
784 |
753 if (err != KErrNone) |
785 if (iSocketPtr == NULL) |
754 { |
786 { |
755 Complete(aStatus, err); |
787 TInt ret = OpenUsingPreference(); |
756 return; |
788 if (ret != KErrNone) |
757 } |
789 { |
758 |
790 Complete(aStatus,ret); // Error in open |
759 TUSockAddr toAddr(anAddr, aAddrLen); |
791 iWriteLock.Signal(); |
760 |
792 return; |
761 iWriteLock.Wait(); |
793 } |
|
794 } |
|
795 TUSockAddr toAddr(anAddr,aAddrLen); |
|
796 CSockDescBase::SendTo(aDesc, toAddr, flags, aStatus); |
762 CSockDescBase::SendTo(aDesc, toAddr, flags, aStatus); |
797 iWriteLock.Signal(); |
763 iWriteLock.Signal(); |
798 } |
764 } |
799 |
765 |
800 void CSocketDesc::SendToCancel() |
766 void CSocketDesc::SendToCancel() |
801 { |
767 { |
|
768 // Should we use atomic loads here? |
802 if (iSocketPtr != NULL) |
769 if (iSocketPtr != NULL) |
803 { |
770 { |
804 CSockDescBase::SendToCancel(); |
771 CSockDescBase::SendToCancel(); |
805 } |
772 } |
806 } |
773 } |
807 |
774 |
808 void CSocketDesc::Shutdown(TUint aHow,TRequestStatus& aStatus) |
775 void CSocketDesc::Shutdown(TUint aHow,TRequestStatus& aStatus) |
809 { |
776 { |
810 if (iSocketPtr == NULL) // Not opened at all. Nothing to do. |
777 |
|
778 if (__e32_atomic_load_acq32(&iSocketPtr) == NULL) // Not opened at all. Nothing to do. |
811 { |
779 { |
812 Complete(aStatus,KErrNone); |
780 Complete(aStatus,KErrNone); |
813 return; |
781 return; |
814 } |
782 } |
815 |
783 |
817 return; |
785 return; |
818 } |
786 } |
819 |
787 |
820 void CSocketDesc::Accept(CFileDescBase*& aNewSocket, TRequestStatus& aStatus, RSocketServ& aSs, TSockAddr * /*aAddr*/) |
788 void CSocketDesc::Accept(CFileDescBase*& aNewSocket, TRequestStatus& aStatus, RSocketServ& aSs, TSockAddr * /*aAddr*/) |
821 { |
789 { |
822 //Acquire the Lock before accept and release it later |
790 aNewSocket = NULL; |
|
791 TInt err = maybe_reopen_socket(); |
|
792 if (err != KErrNone) |
|
793 { |
|
794 Complete(aStatus, err); |
|
795 return; |
|
796 } |
|
797 |
823 iReadLock.Wait(); |
798 iReadLock.Wait(); |
824 |
799 // what are the below coverity thingummichs? |
825 TInt err = KErrNone; |
|
826 if (iSocketPtr == NULL) |
|
827 { |
|
828 err = OpenUsingPreference(); |
|
829 if (err != KErrNone) // Error in open |
|
830 { |
|
831 Complete(aStatus,err); |
|
832 iReadLock.Signal(); |
|
833 return; |
|
834 } |
|
835 } |
|
836 |
|
837 //coverity[alloc_fn] |
800 //coverity[alloc_fn] |
838 //coverity[assign] |
801 //coverity[assign] |
839 CSocketDesc *newSocket = new CSocketDesc; |
802 CSocketDesc *newSocket = new CSocketDesc; |
840 if (newSocket!=0) |
803 if (!newSocket) |
841 { |
804 { |
842 err = newSocket->CreateLock(); |
805 Complete(aStatus, KErrNoMemory); |
843 if (err) |
806 iReadLock.Signal(); |
844 { |
807 return; |
845 Complete(aStatus, KErrNoMemory); |
808 } |
846 delete newSocket; |
809 |
847 aNewSocket = NULL; |
810 err = newSocket->CreateLock(); |
848 iReadLock.Signal(); |
811 if (err) |
849 //coverity[memory_leak] |
812 { |
850 return; |
813 Complete(aStatus, KErrNoMemory); |
851 } |
814 delete newSocket; |
852 |
815 iReadLock.Signal(); |
853 err=newSocket->iSocket.Open(aSs); |
816 //coverity[memory_leak] |
854 } |
817 return; |
855 if (newSocket ==0 || err!=KErrNone) |
818 } |
856 { |
819 |
857 Complete(aStatus,KErrNoMemory); |
820 err = newSocket->iSocket.Open(aSs); |
|
821 if (err) |
|
822 { |
|
823 Complete(aStatus, err); |
|
824 newSocket->FinalClose(); // this will Close locks |
858 delete newSocket; |
825 delete newSocket; |
859 aNewSocket = NULL; |
826 |
860 iReadLock.Signal(); |
827 iReadLock.Signal(); |
861 //coverity[memory_leak] |
828 //coverity[memory_leak] |
862 return; |
829 return; |
863 } |
830 } |
864 newSocket->iSocketPtr = &newSocket->iSocket; |
831 newSocket->iSocketPtr = &newSocket->iSocket; |
865 newSocket->iStyle = iStyle; |
832 newSocket->iStyle = iStyle; |
866 iSocket.Accept(newSocket->iSocket,aStatus); |
833 err = KErrNone; |
867 aNewSocket = newSocket; |
834 ATOMICSOCKETOP( iSocket.Accept(newSocket->iSocket,aStatus), err = KErrBadHandle ) |
|
835 if( err ) |
|
836 { |
|
837 Complete(aStatus, err); |
|
838 newSocket->FinalClose(); // this will Close locks |
|
839 delete newSocket; |
|
840 } |
|
841 else |
|
842 { |
|
843 aNewSocket = newSocket; |
|
844 } |
868 iReadLock.Signal(); |
845 iReadLock.Signal(); |
869 } |
846 } |
870 |
847 |
871 void CSocketDesc::AcceptCancel() |
848 void CSocketDesc::AcceptCancel() |
872 { |
849 { |
873 if (iSocketPtr != NULL) |
850 if (iSocketPtr != NULL) |
874 { |
851 { |
875 iSocket.CancelAccept(); |
852 ATOMICSOCKETOP( iSocket.CancelAccept(), NOP ) |
876 } |
853 } |
877 } |
854 } |
878 |
855 |
879 void CSocketDesc::Connect(const struct sockaddr* aAddr,unsigned long size,TRequestStatus& aStatus) |
856 void CSocketDesc::Connect(const struct sockaddr* aAddr,unsigned long size,TRequestStatus& aStatus) |
880 { |
857 { |
883 if (addr.iError != 0) |
860 if (addr.iError != 0) |
884 { |
861 { |
885 aStatus = addr.iError; |
862 aStatus = addr.iError; |
886 return; |
863 return; |
887 } |
864 } |
888 if (iSocketPtr == NULL) |
865 |
889 { |
866 TInt err = maybe_reopen_socket(); |
890 // RSocket::Open() is postponed from socket() |
867 if (err != KErrNone) |
891 TInt ret = OpenUsingPreference(); |
868 { |
892 if (ret != KErrNone) // error in open |
869 aStatus = err; |
893 { |
870 return; |
894 aStatus = ret; |
871 } |
895 return; |
872 |
896 } |
873 iWriteLock.Wait(); |
897 } |
874 if( GetConnectionProgress() == EFalse ) |
898 |
875 { |
899 iSocket.Connect(addr,aStatus); |
876 ATOMICSOCKETOP(iSocket.Connect(addr, aStatus), Complete(aStatus,KErrBadHandle)) |
900 User::WaitForRequest(aStatus); |
877 User::WaitForRequest(aStatus); |
|
878 if( aStatus.Int() == KErrWouldBlock ) |
|
879 SetConnectionProgress(ETrue); |
|
880 } |
|
881 else |
|
882 { |
|
883 aStatus = EALREADY; |
|
884 } |
|
885 iWriteLock.Signal(); |
901 } |
886 } |
902 |
887 |
903 void CSocketDesc::ConnectCancel() |
888 void CSocketDesc::ConnectCancel() |
904 { |
889 { |
905 if (iSocketPtr != NULL) |
890 if (iSocketPtr != NULL) |
906 { |
891 { |
907 iSocket.CancelConnect(); |
892 ATOMICSOCKETOP(iSocket.CancelConnect(),NOP) |
908 } |
893 } |
909 } |
894 } |
910 |
895 |
911 void CSocketDesc::Ioctl(int aCmd, void* aParam, TRequestStatus& aStatus) |
896 void CSocketDesc::Ioctl(int aCmd, void* aParam, TRequestStatus& aStatus) |
912 { |
897 { |
913 TInt ret=KErrNone; |
898 TInt ret = KErrNone; |
914 int* param = reinterpret_cast<int*>(aParam); |
899 int* param = reinterpret_cast<int*>(aParam); |
915 |
900 |
916 if (iSocketPtr == NULL) |
901 ret = maybe_reopen_socket(); |
917 { |
902 if (ret != KErrNone) |
918 ret = OpenUsingPreference(); |
903 { |
919 if (ret != KErrNone) // Error in open |
904 Complete(aStatus, ret); |
920 { |
905 return; |
921 Complete(aStatus,ret); |
906 } |
922 return; |
|
923 } |
|
924 } |
|
925 |
907 |
926 switch ((unsigned)aCmd) |
908 switch ((unsigned)aCmd) |
927 { |
909 { |
928 case FIONREAD: |
910 case FIONREAD: |
929 case E32IONREAD: |
911 case E32IONREAD: |
930 ret=iSocket.GetOpt(KSOReadBytesPending,KSOLSocket,*param); |
912 { |
|
913 ATOMICSOCKETOP( ret=iSocket.GetOpt(KSOReadBytesPending,KSOLSocket,*param), ret = KErrBadHandle ) |
|
914 } |
931 break; |
915 break; |
932 case E32IOSELECT: |
916 case E32IOSELECT: |
933 { |
917 { |
934 iIoctlBuf.Set((TText8*)aParam,4,4); |
918 iIoctlBuf.Set((TText8*)aParam,4,4); |
935 iIoctlLock.Wait(); |
919 iIoctlLock.Wait(); |
936 iIoctlFlag = ETrue; |
920 iIoctlFlag = ETrue; |
937 iSocket.Ioctl(KIOctlSelect,aStatus,&iIoctlBuf,KSOLSocket); |
921 ATOMICSOCKETOP(iSocket.Ioctl(KIOctlSelect,aStatus,&iIoctlBuf,KSOLSocket), Complete(aStatus,KErrBadHandle)) |
938 } |
922 } |
939 return; |
923 return; |
940 case SIOCGIFCONF: |
924 case SIOCGIFCONF: |
941 ret = GetInterfaceList(aParam); |
925 ret = GetInterfaceList(aParam); |
942 break; |
926 break; |
1024 // As of now fcntl supports F_SETFL and F_GETFL |
1008 // As of now fcntl supports F_SETFL and F_GETFL |
1025 // ----------------------------------------------------------------------------- |
1009 // ----------------------------------------------------------------------------- |
1026 // |
1010 // |
1027 TInt CSocketDesc::Fcntl(TUint anArg, TUint aCmd) |
1011 TInt CSocketDesc::Fcntl(TUint anArg, TUint aCmd) |
1028 { |
1012 { |
1029 if (iSocketPtr == NULL) |
1013 |
1030 { |
1014 TInt err = maybe_reopen_socket(); |
1031 TInt ret = OpenUsingPreference(); |
1015 if (err != KErrNone) |
1032 if (ret != KErrNone) // Error in open |
1016 return err; |
1033 { |
1017 |
1034 return ret; |
1018 return CSockDescBase::Fcntl(anArg, aCmd); |
1035 } |
|
1036 } |
|
1037 return CSockDescBase::Fcntl(anArg, aCmd); |
|
1038 } |
1019 } |
1039 |
1020 |
1040 TInt CSocketDesc :: GetIpAddress( void *aParam ) |
1021 TInt CSocketDesc :: GetIpAddress( void *aParam ) |
1041 { |
1022 { |
1042 TInetAddr myAddr; |
1023 TInetAddr myAddr; |
1043 iSocket.LocalName(myAddr); |
1024 ATOMICSOCKETOP( iSocket.LocalName(myAddr), return KErrBadHandle ) |
1044 TUint32 myIP = myAddr.Address(); |
1025 TUint32 myIP = myAddr.Address(); |
|
1026 if (myIP == 0) |
|
1027 { |
|
1028 return KErrGeneral; |
|
1029 } |
|
1030 |
1045 ifreq *ifr = (ifreq *)aParam; |
1031 ifreq *ifr = (ifreq *)aParam; |
1046 if(myIP == 0) |
|
1047 { |
|
1048 return KErrGeneral; |
|
1049 } |
|
1050 ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr = myIP; |
1032 ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr = myIP; |
1051 return KErrNone; |
1033 return KErrNone; |
1052 } |
1034 } |
1053 |
1035 |
1054 TInt CSocketDesc :: GetRemoteIpAddress( void *aParam ) |
1036 TInt CSocketDesc :: GetRemoteIpAddress( void *aParam ) |
1055 { |
1037 { |
1056 TInetAddr remoteAddr; |
1038 TInetAddr remoteAddr; |
1057 iSocket.RemoteName(remoteAddr); |
1039 ATOMICSOCKETOP( iSocket.RemoteName(remoteAddr), return KErrBadHandle ) |
1058 TUint32 remoteIP = remoteAddr.Address(); |
1040 TUint32 remoteIP = remoteAddr.Address(); |
|
1041 |
|
1042 if (remoteIP == 0) |
|
1043 { |
|
1044 return KErrGeneral; |
|
1045 } |
1059 ifreq *ifr = (ifreq *)aParam; |
1046 ifreq *ifr = (ifreq *)aParam; |
1060 if(remoteIP == 0) |
|
1061 { |
|
1062 return KErrGeneral; |
|
1063 } |
|
1064 ((struct sockaddr_in *)&ifr->ifr_dstaddr)->sin_addr.s_addr = remoteIP; |
1047 ((struct sockaddr_in *)&ifr->ifr_dstaddr)->sin_addr.s_addr = remoteIP; |
1065 return KErrNone; |
1048 return KErrNone; |
1066 } |
1049 } |
1067 |
1050 |
1068 TInt CSocketDesc :: GetInterafceNumber( void *aParam ) |
1051 TInt CSocketDesc :: GetInterafceNumber( void *aParam ) |
1206 { |
1189 { |
1207 ifreq *ifr = (ifreq *)aParam; |
1190 ifreq *ifr = (ifreq *)aParam; |
1208 TPckgBuf<TSoInetIfQuery> ifq; |
1191 TPckgBuf<TSoInetIfQuery> ifq; |
1209 TBuf8 <25> ipBuf8; |
1192 TBuf8 <25> ipBuf8; |
1210 TName aBuf; |
1193 TName aBuf; |
1211 |
1194 TInt ret = KErrNone; |
1212 TInt ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
1195 ATOMICSOCKETOP( ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle ) |
1213 if (ret != KErrNone) |
1196 if (ret != KErrNone) |
1214 { |
1197 { |
1215 return KErrGeneral; |
1198 return KErrGeneral; |
1216 } |
1199 } |
1217 TPckgBuf<TSoInet6InterfaceInfo> info; |
1200 TPckgBuf<TSoInet6InterfaceInfo> info; |
1218 TSoInet6InterfaceInfo &in = info(); |
1201 TSoInet6InterfaceInfo &in = info(); |
1219 |
1202 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle ) |
1220 while(iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info) == KErrNone) |
1203 while(ret == KErrNone) |
1221 { |
1204 { |
1222 if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4")) |
1205 if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4")) |
1223 { |
1206 { |
1224 TDes16& aName = info().iName; |
1207 TDes16& aName = info().iName; |
1225 if( ((aFlag == 0 ) && ( aName.FindC(_L("WLAN")) != KErrNotFound )) || |
1208 if( ((aFlag == 0 ) && ( aName.FindC(_L("WLAN")) != KErrNotFound )) || |
1322 default: |
1305 default: |
1323 break; |
1306 break; |
1324 } |
1307 } |
1325 } |
1308 } |
1326 |
1309 |
1327 } |
1310 } |
|
1311 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle ) |
1328 } |
1312 } |
1329 setout: |
1313 setout: |
1330 TPckgBuf<TSoInet6InterfaceInfo> changeToNew(info()); |
1314 TPckgBuf<TSoInet6InterfaceInfo> changeToNew(info()); |
1331 return iSocket.SetOpt(KSoInetConfigInterface, KSolInetIfCtrl,changeToNew); |
1315 ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetConfigInterface, KSolInetIfCtrl,changeToNew), return KErrBadHandle ) |
|
1316 return ret; |
1332 } |
1317 } |
1333 #endif // __SYMBIAN_COMPILE_UNUSED__ |
1318 #endif // __SYMBIAN_COMPILE_UNUSED__ |
1334 |
1319 |
1335 TInt CSocketDesc::GetInterfaceDetails( void *aParam ,TInt aFlag, TInt aType ) |
1320 TInt CSocketDesc::GetInterfaceDetails( void *aParam ,TInt aFlag, TInt aType ) |
1336 { |
1321 { |
|
1322 TPckgBuf<TSoInetIfQuery> ifq; |
|
1323 |
|
1324 TInt ret = KErrNone; |
|
1325 ATOMICSOCKETOP( ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle ) |
|
1326 if (ret != KErrNone) |
|
1327 { |
|
1328 return KErrGeneral; |
|
1329 } |
|
1330 |
1337 ifreq *ifr = (ifreq *)aParam; |
1331 ifreq *ifr = (ifreq *)aParam; |
1338 TPckgBuf<TSoInetIfQuery> ifq; |
|
1339 |
|
1340 TInt ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
|
1341 if (ret != KErrNone) |
|
1342 { |
|
1343 return KErrGeneral; |
|
1344 } |
|
1345 *(ifr->ifr_addr.sa_data) = '\0'; |
1332 *(ifr->ifr_addr.sa_data) = '\0'; |
1346 |
1333 |
1347 TPckgBuf<TSoInetInterfaceInfo> info; |
1334 TPckgBuf<TSoInetInterfaceInfo> info; |
1348 while(iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info) == KErrNone) |
1335 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle ) |
|
1336 while( ret == KErrNone) |
1349 { |
1337 { |
1350 |
1338 |
1351 if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4")) |
1339 if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4")) |
1352 { |
1340 { |
1353 TDes16& aName = info().iName; |
1341 TDes16& aName = info().iName; |
1458 /* if(info().iFeatures&KIfCanSetMTU) |
1446 /* if(info().iFeatures&KIfCanSetMTU) |
1459 if(info().iFeatures&KIfHasHardwareAddr) |
1447 if(info().iFeatures&KIfHasHardwareAddr) |
1460 if(info().iFeatures&KIfCanSetHardwareAddr) */ |
1448 if(info().iFeatures&KIfCanSetHardwareAddr) */ |
1461 |
1449 |
1462 break; |
1450 break; |
1463 default: |
1451 |
1464 break; |
|
1465 } |
1452 } |
1466 } |
1453 } |
1467 |
1454 |
1468 } |
1455 } |
|
1456 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle ) |
1469 } |
1457 } |
1470 |
1458 |
1471 return KErrNone; |
1459 return KErrNone; |
1472 } |
1460 } |
1473 |
1461 |
1474 TInt CSocketDesc::Poll(TPollMode aMode,TBool& aReadyStatus,TInt& aErrno) |
1462 TInt CSocketDesc::Poll(TPollMode aMode,TBool& aReadyStatus,TInt& aErrno) |
1475 { |
1463 { |
1476 TInt ret; |
1464 TInt ret = maybe_reopen_socket(); |
1477 |
1465 if (ret != KErrNone) |
1478 if (iSocketPtr == NULL) |
1466 { |
1479 { |
1467 return ret; |
1480 ret = OpenUsingPreference(); |
1468 } |
1481 if (ret != KErrNone) // Error in open |
|
1482 { |
|
1483 return ret; |
|
1484 } |
|
1485 } |
|
1486 |
1469 |
1487 TInt status; |
1470 TInt status; |
1488 ret = iSocket.GetOpt(KSOSelectPoll, KSOLSocket, status); |
1471 ATOMICSOCKETOP(ret = iSocket.GetOpt(KSOSelectPoll, KSOLSocket, status), ret = KErrBadHandle) |
1489 if (ret == KErrNone) |
1472 if (ret == KErrNone) |
1490 { |
1473 { |
1491 aReadyStatus = status & aMode; |
1474 aReadyStatus = status & aMode; |
1492 } |
1475 } |
1493 |
1476 |
1771 Backend()->AddSocket(this); |
1750 Backend()->AddSocket(this); |
1772 } |
1751 } |
1773 } |
1752 } |
1774 else // No connection preference is set |
1753 else // No connection preference is set |
1775 { |
1754 { |
1776 ret = iSocket.Open(*iSockServPtr,addrfamily,iStyle,iProtocol); |
1755 ret = ECONNABORTED; |
1777 } |
1756 } |
1778 } |
1757 } |
1779 |
1758 |
1780 if(KErrNone == ret) |
1759 if (ret == KErrNone) |
1781 { |
1760 { |
1782 iSocketPtr = &iSocket; |
1761 __e32_atomic_store_rel32(&iSocketPtr, (unsigned long)&iSocket); |
1783 } |
1762 } |
1784 iConnectInProgress = EFalse; |
1763 |
1785 return ret; |
1764 iConnectInProgress = EFalse; |
1786 } |
1765 |
|
1766 return ret; |
|
1767 } |
1787 |
1768 |
1788 void CSocketDesc::TempClose() |
1769 void CSocketDesc::TempClose() |
1789 { |
1770 { |
|
1771 TUint32 ret = __e32_atomic_ior_ord32((void *)&iCount,0x8000); |
|
1772 if( ret >= 0x8000 ) |
|
1773 { |
|
1774 // This indicates a TempClose has already been done from one of the threads |
|
1775 return; |
|
1776 } |
|
1777 // loop and yeild till no more references are held to the iSocket |
|
1778 while( iCount != 0x8000 ) |
|
1779 { |
|
1780 // Yeild for 1 ms |
|
1781 User::After(1000); |
|
1782 } |
1790 if (iSocket.SubSessionHandle() != 0) |
1783 if (iSocket.SubSessionHandle() != 0) |
1791 { |
1784 { |
1792 iSocketPtr = NULL; |
1785 iSocketPtr = NULL; |
1793 iSocket.CancelAll(); |
1786 iSocket.CancelAll(); |
1794 TRequestStatus status; |
1787 TRequestStatus status; |
2173 return KErrNone; |
2167 return KErrNone; |
2174 } |
2168 } |
2175 |
2169 |
2176 TInt CSocketDesc::GetInterfaceByName(const TDesC& aIfName, TPckgBuf<TSoInetInterfaceInfo>& aIface) |
2170 TInt CSocketDesc::GetInterfaceByName(const TDesC& aIfName, TPckgBuf<TSoInetInterfaceInfo>& aIface) |
2177 { |
2171 { |
2178 TInt ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl); |
2172 TInt ret = KErrNone; |
|
2173 ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle) |
2179 if (ret != KErrNone) |
2174 if (ret != KErrNone) |
2180 { |
2175 { |
2181 return ret; |
2176 return ret; |
2182 } |
2177 } |
2183 TPckgBuf<TSoInetInterfaceInfo> iface; |
2178 TPckgBuf<TSoInetInterfaceInfo> iface; |
2184 while((ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface)) == KErrNone) |
2179 ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle) |
2185 { |
2180 while(ret == KErrNone) |
2186 if(!iface().iAddress.IsUnspecified() |
2181 { |
2187 && iface().iName.CompareF(aIfName) == 0) |
2182 if (!iface().iAddress.IsUnspecified() && iface().iName.CompareF(aIfName) == 0) |
2188 { |
2183 { |
2189 aIface = iface; |
2184 aIface = iface; |
2190 return ret; |
2185 return ret; |
2191 } |
2186 } |
|
2187 ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle ) |
2192 } |
2188 } |
2193 |
|
2194 return KErrUnknown; |
2189 return KErrUnknown; |
2195 } |
2190 } |
2196 |
2191 |
2197 TInt CSocketDesc::GetInterfaceHWAddress(void *aParam) |
2192 TInt CSocketDesc::GetInterfaceHWAddress(void *aParam) |
2198 { |
2193 { |
2201 if (!ifr) |
2196 if (!ifr) |
2202 { |
2197 { |
2203 return KErrArgument; |
2198 return KErrArgument; |
2204 } |
2199 } |
2205 |
2200 |
2206 if (ifr->ifr_name[0]!='\0') |
2201 if (ifr->ifr_name[0] != '\0') |
2207 { |
2202 { |
2208 TPckgBuf<TSoInetInterfaceInfo> iface; |
2203 TPckgBuf<TSoInetInterfaceInfo> iface; |
2209 TFileName name; |
2204 TFileName name; |
2210 name.Copy(TPtrC8((TText8*)ifr->ifr_name)); |
2205 ifr->ifr_name[IFNAMSIZ-1] = 0; // don't assume NULL terminated input |
2211 |
2206 name.Copy(TPtrC8((TText8*)ifr->ifr_name)); |
2212 TInt ret = GetInterfaceByName(name, iface); |
2207 |
2213 |
2208 TInt ret = GetInterfaceByName(name, iface); |
2214 if (ret != KErrNone) |
2209 if (ret != KErrNone) |
2215 { |
2210 return ret; |
2216 return ret; |
2211 |
2217 } |
2212 if (iface().iHwAddr.Length() > sizeof(SSockAddr)) |
2218 |
2213 { |
2219 if(iface().iHwAddr.Length() > sizeof(SSockAddr)) |
2214 Mem::Copy(&(ifr->ifr_hwaddr.sa_data[0]),&(iface().iHwAddr[sizeof(SSockAddr)]), 6); |
2220 { |
2215 ifr->ifr_hwaddr.sa_family = (TUint16)iface().iHwAddr.Family(); |
2221 Mem::Copy(&(ifr->ifr_hwaddr.sa_data[0]),&(iface().iHwAddr[sizeof(SSockAddr)]), 6); |
2216 ifr->ifr_hwaddr.sa_port = ByteOrder::Swap16(iface().iHwAddr.Port()); |
2222 ifr->ifr_hwaddr.sa_family = (TUint16)iface().iHwAddr.Family(); |
2217 return ret; |
2223 ifr->ifr_hwaddr.sa_port = ByteOrder::Swap16(iface().iHwAddr.Port()); |
2218 } |
2224 return ret; |
2219 } |
2225 } |
|
2226 } |
|
2227 |
2220 |
2228 return KErrUnknown; |
2221 return KErrUnknown; |
2229 } |
2222 } |
2230 |
2223 |
2231 //This function retrieves the Currently active IAP ID using the RSocket Query. |
2224 //This function retrieves the Currently active IAP ID using the RSocket Query. |
2234 //will contain the snap id. User is supposed to call if_indextoname() api to get the IAP name |
2227 //will contain the snap id. User is supposed to call if_indextoname() api to get the IAP name |
2235 //from the ID retured with this Ioctl implementation. |
2228 //from the ID retured with this Ioctl implementation. |
2236 TInt CSocketDesc::GetActiveInterface( void *aParam) |
2229 TInt CSocketDesc::GetActiveInterface( void *aParam) |
2237 { |
2230 { |
2238 TInt ifindex = -1; |
2231 TInt ifindex = -1; |
2239 TInt ret = iSocket.GetOpt(KSoInterfaceIndex, KSolInetIp , ifindex); |
2232 TInt ret = KErrNone; |
|
2233 ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInterfaceIndex, KSolInetIp , ifindex), ret = KErrBadHandle) |
2240 if(ret!=KErrNone) |
2234 if(ret!=KErrNone) |
2241 { |
2235 { |
2242 return ret; |
2236 return ret; |
2243 } |
2237 } |
2244 TPckgBuf<TSoInetIfQuery> opt; |
2238 TPckgBuf<TSoInetIfQuery> opt; |
2245 opt().iIndex = ifindex; |
2239 opt().iIndex = ifindex; |
2246 ret = iSocket.GetOpt(KSoInetIfQueryByIndex, KSolInetIfQuery, opt); |
2240 ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInetIfQueryByIndex, KSolInetIfQuery, opt), ret = KErrBadHandle) |
2247 if(ret!=KErrNone) |
2241 if(ret!=KErrNone) |
2248 { |
2242 { |
2249 return ret; |
2243 return ret; |
2250 } |
2244 } |
2251 ifreq *ifr = (ifreq * )aParam; |
2245 ifreq *ifr = (ifreq * )aParam; |