diff --git a/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp b/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp index e38c87068f..72ce4f253b 100644 --- a/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp +++ b/src/add-ons/kernel/network/interfaces/ppp/PPPManager.cpp @@ -746,12 +746,11 @@ PPPManager::SettingsChanged() { // get default interface name and update interfaces if it changed void *handle = load_driver_settings("ptpnet.settings"); - char *name = get_driver_parameter(handle, "default", NULL, NULL); - if(name) - name = strdup(name); + const char *name = get_driver_parameter(handle, "default", NULL, NULL); unload_driver_settings(handle); - if((!fDefaultInterface && !name) || !strcmp(name, fDefaultInterface)) + if((!fDefaultInterface && !name) || (fDefaultInterface && name + && !strcmp(name, fDefaultInterface))) return; ppp_interface_entry *entry = EntryFor(fDefaultInterface); @@ -759,9 +758,13 @@ PPPManager::SettingsChanged() && entry->interface->StateMachine().Phase() == PPP_DOWN_PHASE) DeleteInterface(entry->interface->ID()); - free(fInterfaceName); - fInterfaceName = name; + free(fDefaultInterface); + if(!name) { + fDefaultInterface = NULL; + return; + } + fDefaultInterface = strdup(name); ppp_interface_id id = CreateInterfaceWithName(name); entry = EntryFor(id); if(entry && entry->interface) diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile b/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile index 43c0167ee8..495aa82fea 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/Jamfile @@ -12,6 +12,7 @@ UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkerne R5KernelStaticLibrary kernelppp : + atomic.S kernel_cpp.cpp KPPPConfigurePacket.cpp diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp index c2e7b3cecf..33adb6a334 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPInterface.cpp @@ -423,6 +423,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length) info->connectRetriesLimit = fConnectRetriesLimit; info->connectRetryDelay = ConnectRetryDelay(); info->reconnectDelay = ReconnectDelay(); + info->connectedSince = ConnectedSince(); info->idleSince = IdleSince(); info->disconnectAfterIdleSince = DisconnectAfterIdleSince(); info->doesConnectOnDemand = DoesConnectOnDemand(); @@ -1389,14 +1390,8 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber) return B_ERROR; } - // TODO: always use atomic_add64 when Haiku is finished -#ifdef __HAIKU__ atomic_add64(&fStatistics.bytesSent, length); atomic_add64(&fStatistics.packetsSent, 1); -#else - atomic_add((int32*) &fStatistics.bytesSent, length); - atomic_add((int32*) &fStatistics.packetsSent, 1); -#endif return SendToNext(packet, 0); // this is normally the device, but there can be something inbetween } else { @@ -1518,14 +1513,8 @@ KPPPInterface::ReceiveFromDevice(struct mbuf *packet) m_adj(packet, 2); } - // TODO: always use atomic_add64 when Haiku is finished -#ifdef __HAIKU__ atomic_add64(&fStatistics.bytesReceived, length); atomic_add64(&fStatistics.packetsReceived, 1); -#else - atomic_add((int32*) &fStatistics.bytesReceived, length); - atomic_add((int32*) &fStatistics.packetsReceived, 1); -#endif return Receive(packet, protocolNumber); } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp index f677727008..41409ad500 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPStateMachine.cpp @@ -124,12 +124,13 @@ KPPPStateMachine::NewPhase(ppp_phase next) fPhase = next; if(Phase() == PPP_ESTABLISHED_PHASE) { + Interface().fConnectedSince = system_time(); + if(Interface().Ifnet()) Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING; Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_UP_SUCCESSFUL, &fInterface.fID, sizeof(ppp_interface_id)); - Interface().fConnectedSince = system_time(); } } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/TODO b/src/add-ons/kernel/network/ppp/shared/libkernelppp/TODO index 33f9f1ed24..382b9be52d 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/TODO +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/TODO @@ -1,3 +1,4 @@ +- remove atomic.S when Haiku is finished - add missing settings support (ConnectRetryDelay, etc.) - finish support for server mode (profiles, etc.) - add callback support diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/atomic.S b/src/add-ons/kernel/network/ppp/shared/libkernelppp/atomic.S new file mode 100644 index 0000000000..44a5564d87 --- /dev/null +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/atomic.S @@ -0,0 +1,117 @@ +/* +** Copyright 2003, Marcus Overhagen. All rights reserved. +** Distributed under the terms of the OpenBeOS license. +** +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#define FUNCTION(x) .global x; .type x,@function; x + +.text + +/* int64 atomic_set64(vint64 *value, int64 newValue) */ +FUNCTION(atomic_set64): + push %ebp + push %ebx + movl 12(%esp), %ebp /* value */ + movl 16(%esp), %ebx /* newValue low */ + movl 20(%esp), %ecx /* newValue high */ +_atomic_set64_1: + movl (%ebp), %eax /* testAgainst low */ + movl 4(%ebp), %edx /* testAgainst high */ + lock + cmpxchg8b (%ebp) + jnz _atomic_set64_1 + pop %ebx + pop %ebp + ret + +/* int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst) */ +FUNCTION(atomic_test_and_set64): + push %ebp + push %ebx + movl 12(%esp), %ebp /* value */ + movl 16(%esp), %ebx /* newValue low */ + movl 20(%esp), %ecx /* newValue high */ + movl 24(%esp), %eax /* testAgainst low */ + movl 28(%esp), %edx /* testAgainst high */ + lock + cmpxchg8b (%ebp) + pop %ebx + pop %ebp + ret + +/* int64 atomic_add64(vint64 *value, int64 addValue) */ +FUNCTION(atomic_add64): + push %ebp + push %ebx + movl 12(%esp), %ebp +_atomic_add64_1: + movl (%ebp), %eax + movl 4(%ebp), %edx + movl %eax, %ebx + movl %edx, %ecx + addl 16(%esp), %ebx + adcl 20(%esp), %ecx + lock + cmpxchg8b (%ebp) + jnz _atomic_add64_1 + pop %ebx + pop %ebp + ret + +/* int64 atomic_and64(vint64 *value, int64 andValue) */ +FUNCTION(atomic_and64): + push %ebp + push %ebx + movl 12(%esp), %ebp +_atomic_and64_1: + movl (%ebp), %eax + movl 4(%ebp), %edx + movl %eax, %ebx + movl %edx, %ecx + andl 16(%esp), %ebx + andl 20(%esp), %ecx + lock + cmpxchg8b (%ebp) + jnz _atomic_and64_1 + pop %ebx + pop %ebp + ret + +/* int64 atomic_or64(vint64 *value, int64 orValue) */ +FUNCTION(atomic_or64): + push %ebp + push %ebx + movl 12(%esp), %ebp +_atomic_or64_1: + movl (%ebp), %eax + movl 4(%ebp), %edx + movl %eax, %ebx + movl %edx, %ecx + orl 16(%esp), %ebx + orl 20(%esp), %ecx + lock + cmpxchg8b (%ebp) + jnz _atomic_or64_1 + pop %ebx + pop %ebp + ret + +/* int64 atomic_get64(vint64 *value) */ +FUNCTION(atomic_get64): + push %ebp + push %ebx + movl 12(%esp), %ebp +_atomic_get64_1: + movl (%ebp), %eax + movl 4(%ebp), %edx + movl %eax, %ebx + movl %edx, %ecx + lock + cmpxchg8b (%ebp) + jnz _atomic_get64_1 + pop %ebx + pop %ebp + ret diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h index ee02cbec00..9ef1e4b9a1 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h @@ -93,6 +93,10 @@ class KPPPInterface : public KPPPLayer { uint32 ReconnectDelay() const { return fReconnectDelay; } + //! Time when connection was established successfully. + bigtime_t ConnectedSince() const + { return fConnectedSince; } + //! Used for reporting that a packet was send/received (updates idle time). void UpdateIdleSince() { fUpdateIdleSince = true; } diff --git a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h index b4985824bc..504a321af9 100644 --- a/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h +++ b/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/PPPControl.h @@ -172,14 +172,14 @@ typedef struct ppp_interface_info_t { //! Structure used by \c PPPC_GET_STATISTICS. typedef struct ppp_statistics { - uint64 bytesReceived, packetsReceived; - uint64 bytesSent, packetsSent; + int64 bytesReceived, packetsReceived; + int64 bytesSent, packetsSent; // TODO: currently unused - uint64 errorBytesReceived, errorPacketsReceived; + int64 errorBytesReceived, errorPacketsReceived; // TODO: add compression statistics? - uint8 _reserved_[80]; + int8 _reserved_[80]; } ppp_statistics; //! Structure used by \c PPPC_GET_DEVICE_INFO. diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterface.cpp b/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterface.cpp index d9ac67ba63..6f7aed5da6 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterface.cpp +++ b/src/add-ons/kernel/network/ppp/shared/libppp/PPPInterface.cpp @@ -181,6 +181,22 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const } +/*! \brief Get transfer statistics for this interface. + + \param statistics The structure is copied into this argument. + + \return \c true on success, \c false otherwise. +*/ +bool +PPPInterface::GetStatistics(ppp_statistics *statistics) const +{ + if(!statistics) + return false; + + return Control(PPPC_GET_STATISTICS, statistics, sizeof(ppp_statistics)) == B_OK; +} + + //! Compares interface's settings to given driver_settings structure. bool PPPInterface::HasSettings(const driver_settings *settings) const diff --git a/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterface.h b/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterface.h index 38625b82bf..ae1a51fe17 100644 --- a/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterface.h +++ b/src/add-ons/kernel/network/ppp/shared/libppp/headers/PPPInterface.h @@ -32,6 +32,7 @@ class PPPInterface { status_t GetSettingsEntry(BEntry *entry) const; bool GetInterfaceInfo(ppp_interface_info_t *info) const; + bool GetStatistics(ppp_statistics *statistics) const; bool HasSettings(const driver_settings *settings) const; void SetProfile(const driver_settings *profile) const;