• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "chpp/services.h"
18 
19 #include <inttypes.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "chpp/app.h"
25 #include "chpp/log.h"
26 #include "chpp/macros.h"
27 #include "chpp/memory.h"
28 #include "chpp/mutex.h"
29 #ifdef CHPP_SERVICE_ENABLED_GNSS
30 #include "chpp/services/gnss.h"
31 #endif
32 #ifdef CHPP_SERVICE_ENABLED_WIFI
33 #include "chpp/services/wifi.h"
34 #endif
35 #ifdef CHPP_SERVICE_ENABLED_WWAN
36 #include "chpp/services/wwan.h"
37 #endif
38 #include "chpp/transport.h"
39 
40 /************************************************
41  *  Public Functions
42  ***********************************************/
43 
chppRegisterCommonServices(struct ChppAppState * context)44 void chppRegisterCommonServices(struct ChppAppState *context) {
45   CHPP_DEBUG_NOT_NULL(context);
46   UNUSED_VAR(context);
47 
48 #ifdef CHPP_SERVICE_ENABLED_WWAN
49   if (context->clientServiceSet.wwanService) {
50     chppRegisterWwanService(context);
51   }
52 #endif
53 
54 #ifdef CHPP_SERVICE_ENABLED_WIFI
55   if (context->clientServiceSet.wifiService) {
56     chppRegisterWifiService(context);
57   }
58 #endif
59 
60 #ifdef CHPP_SERVICE_ENABLED_GNSS
61   if (context->clientServiceSet.gnssService) {
62     chppRegisterGnssService(context);
63   }
64 #endif
65 }
66 
chppDeregisterCommonServices(struct ChppAppState * context)67 void chppDeregisterCommonServices(struct ChppAppState *context) {
68   CHPP_DEBUG_NOT_NULL(context);
69   UNUSED_VAR(context);
70 
71 #ifdef CHPP_SERVICE_ENABLED_WWAN
72   if (context->clientServiceSet.wwanService) {
73     chppDeregisterWwanService(context);
74   }
75 #endif
76 
77 #ifdef CHPP_SERVICE_ENABLED_WIFI
78   if (context->clientServiceSet.wifiService) {
79     chppDeregisterWifiService(context);
80   }
81 #endif
82 
83 #ifdef CHPP_SERVICE_ENABLED_GNSS
84   if (context->clientServiceSet.gnssService) {
85     chppDeregisterGnssService(context);
86   }
87 #endif
88 }
89 
chppRegisterService(struct ChppAppState * appContext,void * serviceContext,struct ChppEndpointState * serviceState,struct ChppOutgoingRequestState * outReqStates,const struct ChppService * newService)90 void chppRegisterService(struct ChppAppState *appContext, void *serviceContext,
91                          struct ChppEndpointState *serviceState,
92                          struct ChppOutgoingRequestState *outReqStates,
93                          const struct ChppService *newService) {
94   CHPP_DEBUG_NOT_NULL(appContext);
95   CHPP_DEBUG_NOT_NULL(serviceContext);
96   CHPP_DEBUG_NOT_NULL(serviceState);
97   CHPP_DEBUG_NOT_NULL(newService);
98 
99   const uint8_t numServices = appContext->registeredServiceCount;
100 
101   serviceState->openState = CHPP_OPEN_STATE_CLOSED;
102   serviceState->appContext = appContext;
103   serviceState->outReqStates = outReqStates;
104   serviceState->context = serviceContext;
105   serviceState->nextTimerTimeoutNs = CHPP_TIME_MAX;
106 
107   if (numServices >= CHPP_MAX_REGISTERED_SERVICES) {
108     CHPP_LOGE("Max services registered: # %" PRIu8, numServices);
109     serviceState->handle = CHPP_HANDLE_NONE;
110     return;
111   }
112 
113   serviceState->index = numServices;
114   serviceState->handle = CHPP_SERVICE_HANDLE_OF_INDEX(numServices);
115 
116   appContext->registeredServices[numServices] = newService;
117   appContext->registeredServiceStates[numServices] = serviceState;
118   appContext->registeredServiceCount++;
119 
120   chppMutexInit(&serviceState->syncResponse.mutex);
121   chppConditionVariableInit(&serviceState->syncResponse.condVar);
122 
123   char uuidText[CHPP_SERVICE_UUID_STRING_LEN];
124   chppUuidToStr(newService->descriptor.uuid, uuidText);
125   CHPP_LOGD("Registered service # %" PRIu8
126             " on handle %d"
127             " with name=%s, UUID=%s, version=%" PRIu8 ".%" PRIu8 ".%" PRIu16
128             ", min_len=%" PRIuSIZE " ",
129             numServices, serviceState->handle, newService->descriptor.name,
130             uuidText, newService->descriptor.version.major,
131             newService->descriptor.version.minor,
132             newService->descriptor.version.patch, newService->minLength);
133 }
134 
chppAllocServiceNotification(size_t len)135 struct ChppAppHeader *chppAllocServiceNotification(size_t len) {
136   return chppAllocNotification(CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION, len);
137 }
138 
chppAllocServiceRequest(struct ChppEndpointState * serviceState,size_t len)139 struct ChppAppHeader *chppAllocServiceRequest(
140     struct ChppEndpointState *serviceState, size_t len) {
141   CHPP_DEBUG_NOT_NULL(serviceState);
142   return chppAllocRequest(CHPP_MESSAGE_TYPE_SERVICE_REQUEST, serviceState, len);
143 }
144 
chppAllocServiceRequestCommand(struct ChppEndpointState * serviceState,uint16_t command)145 struct ChppAppHeader *chppAllocServiceRequestCommand(
146     struct ChppEndpointState *serviceState, uint16_t command) {
147   struct ChppAppHeader *request =
148       chppAllocServiceRequest(serviceState, sizeof(struct ChppAppHeader));
149 
150   if (request != NULL) {
151     request->command = command;
152   }
153   return request;
154 }
155 
chppServiceSendTimestampedRequestOrFail(struct ChppEndpointState * serviceState,struct ChppOutgoingRequestState * outReqState,void * buf,size_t len,uint64_t timeoutNs)156 bool chppServiceSendTimestampedRequestOrFail(
157     struct ChppEndpointState *serviceState,
158     struct ChppOutgoingRequestState *outReqState, void *buf, size_t len,
159     uint64_t timeoutNs) {
160   return chppSendTimestampedRequestOrFail(serviceState, outReqState, buf, len,
161                                           timeoutNs);
162 }
163 
chppServiceSendTimestampedRequestAndWait(struct ChppEndpointState * serviceState,struct ChppOutgoingRequestState * outReqState,void * buf,size_t len)164 bool chppServiceSendTimestampedRequestAndWait(
165     struct ChppEndpointState *serviceState,
166     struct ChppOutgoingRequestState *outReqState, void *buf, size_t len) {
167   return chppServiceSendTimestampedRequestAndWaitTimeout(
168       serviceState, outReqState, buf, len, CHPP_REQUEST_TIMEOUT_DEFAULT);
169 }
170 
chppServiceSendTimestampedRequestAndWaitTimeout(struct ChppEndpointState * serviceState,struct ChppOutgoingRequestState * outReqState,void * buf,size_t len,uint64_t timeoutNs)171 bool chppServiceSendTimestampedRequestAndWaitTimeout(
172     struct ChppEndpointState *serviceState,
173     struct ChppOutgoingRequestState *outReqState, void *buf, size_t len,
174     uint64_t timeoutNs) {
175   CHPP_DEBUG_NOT_NULL(serviceState);
176 
177   bool result = chppServiceSendTimestampedRequestOrFail(
178       serviceState, outReqState, buf, len, CHPP_REQUEST_TIMEOUT_INFINITE);
179 
180   if (!result) {
181     return false;
182   }
183 
184   return chppWaitForResponseWithTimeout(&serviceState->syncResponse,
185                                         outReqState, timeoutNs);
186 }
187 
chppServiceCloseOpenRequests(struct ChppEndpointState * serviceState,const struct ChppService * service,bool clearOnly)188 void chppServiceCloseOpenRequests(struct ChppEndpointState *serviceState,
189                                   const struct ChppService *service,
190                                   bool clearOnly) {
191   UNUSED_VAR(service);
192   chppCloseOpenRequests(serviceState, CHPP_ENDPOINT_SERVICE, clearOnly);
193 }