summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2015-04-08 10:59:37 +0300
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2016-03-11 11:36:54 +0200
commit0054d1419f18795df710caac274a8a5dec7b1a0f (patch)
tree7da3e47c4a6e16aece1c12da57eb4b4839e8e489
parent628ee2b4c5b082f6fad402814a6d1743c369af2a (diff)
downloadbluez-0054d1419f18795df710caac274a8a5dec7b1a0f.tar.gz
core/service: Add btd_service_reconnect
This mark the service to reconnect so plugins such as policy can indicate the service will be reconnected.
-rw-r--r--src/service.c33
-rw-r--r--src/service.h2
2 files changed, 35 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;
+}
diff --git a/src/service.h b/src/service.h
index a1db44fd6..2c315f504 100644
--- a/src/service.h
+++ b/src/service.h
@@ -76,3 +76,5 @@ void btd_service_connecting_complete(struct btd_service *service, int err);
void btd_service_disconnecting_complete(struct btd_service *service, int err);
void btd_service_set_user_data(struct btd_service *service, void *user_data);
void *btd_service_get_user_data(const struct btd_service *service);
+void btd_service_reconnect(struct btd_service *service, bool value);
+bool btd_service_is_reconnecting(struct btd_service *service);