summaryrefslogtreecommitdiff
path: root/src/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service.c')
-rw-r--r--src/service.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/service.c b/src/service.c
index 4f0328b8f..4284459bc 100644
--- a/src/service.c
+++ b/src/service.c
@@ -57,6 +57,7 @@ struct btd_service {
int err;
bool auto_connect;
bool blocked;
+ bool reconnecting;
};
struct service_state_callback {
@@ -101,6 +102,9 @@ static void change_state(struct btd_service *service, btd_service_state_t state,
service->state = state;
service->err = err;
+ if (state == BTD_SERVICE_STATE_CONNECTED)
+ service->reconnecting = false;
+
ba2str(device_get_address(service->device), addr);
DBG("%p: device %s profile %s state changed: %s -> %s (%d)", service,
addr, service->profile->name,
@@ -111,6 +115,10 @@ static void change_state(struct btd_service *service, btd_service_state_t state,
cb->cb(service, old, state, cb->user_data);
}
+
+ /* Change state back to connecting if reconnect flag is set */
+ if (service->reconnecting && state == BTD_SERVICE_STATE_DISCONNECTED)
+ change_state(service, BTD_SERVICE_STATE_CONNECTING, err);
}
struct btd_service *btd_service_ref(struct btd_service *service)
@@ -232,6 +240,8 @@ int btd_service_connect(struct btd_service *service)
case BTD_SERVICE_STATE_DISCONNECTED:
break;
case BTD_SERVICE_STATE_CONNECTING:
+ if (service->reconnecting)
+ break;
return 0;
case BTD_SERVICE_STATE_CONNECTED:
return -EALREADY;
@@ -315,6 +325,11 @@ void *btd_service_get_user_data(const struct btd_service *service)
btd_service_state_t btd_service_get_state(const struct btd_service *service)
{
+ /* Return connecting if reconnection policy is active */
+ if (service->state == BTD_SERVICE_STATE_DISCONNECTED &&
+ service->reconnecting)
+ return BTD_SERVICE_STATE_CONNECTING;
+
return service->state;
}
@@ -422,3 +437,21 @@ void btd_service_disconnecting_complete(struct btd_service *service, int err)
else /* If disconnect fails, we assume it remains connected */
change_state(service, BTD_SERVICE_STATE_CONNECTED, err);
}
+
+void btd_service_reconnect(struct btd_service *service, bool value)
+{
+ service->reconnecting = value;
+
+ /* Don't change state if already connected */
+ if (service->state == BTD_SERVICE_STATE_CONNECTED)
+ return;
+
+ change_state(service, value ? BTD_SERVICE_STATE_CONNECTING :
+ BTD_SERVICE_STATE_DISCONNECTED,
+ value ? 0 : -EHOSTDOWN);
+}
+
+bool btd_service_is_reconnecting(struct btd_service *service)
+{
+ return service->reconnecting;
+}