• 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/memory.h"
27 #ifdef CHPP_SERVICE_ENABLED_GNSS
28 #include "chpp/services/gnss.h"
29 #endif
30 #ifdef CHPP_SERVICE_ENABLED_WIFI
31 #include "chpp/services/wifi.h"
32 #endif
33 #ifdef CHPP_SERVICE_ENABLED_WWAN
34 #include "chpp/services/wwan.h"
35 #endif
36 #include "chpp/time.h"
37 #include "chpp/transport.h"
38 
39 /************************************************
40  *  Public Functions
41  ***********************************************/
42 
chppRegisterCommonServices(struct ChppAppState * context)43 void chppRegisterCommonServices(struct ChppAppState *context) {
44   UNUSED_VAR(context);
45 
46 #ifdef CHPP_SERVICE_ENABLED_WWAN
47   if (context->clientServiceSet.wwanService) {
48     chppRegisterWwanService(context);
49   }
50 #endif
51 
52 #ifdef CHPP_SERVICE_ENABLED_WIFI
53   if (context->clientServiceSet.wifiService) {
54     chppRegisterWifiService(context);
55   }
56 #endif
57 
58 #ifdef CHPP_SERVICE_ENABLED_GNSS
59   if (context->clientServiceSet.gnssService) {
60     chppRegisterGnssService(context);
61   }
62 #endif
63 }
64 
chppDeregisterCommonServices(struct ChppAppState * context)65 void chppDeregisterCommonServices(struct ChppAppState *context) {
66   UNUSED_VAR(context);
67 
68 #ifdef CHPP_SERVICE_ENABLED_WWAN
69   if (context->clientServiceSet.wwanService) {
70     chppDeregisterWwanService(context);
71   }
72 #endif
73 
74 #ifdef CHPP_SERVICE_ENABLED_WIFI
75   if (context->clientServiceSet.wifiService) {
76     chppDeregisterWifiService(context);
77   }
78 #endif
79 
80 #ifdef CHPP_SERVICE_ENABLED_GNSS
81   if (context->clientServiceSet.gnssService) {
82     chppDeregisterGnssService(context);
83   }
84 #endif
85 }
86 
chppRegisterService(struct ChppAppState * appContext,void * serviceContext,struct ChppServiceState * serviceState,const struct ChppService * newService)87 void chppRegisterService(struct ChppAppState *appContext, void *serviceContext,
88                          struct ChppServiceState *serviceState,
89                          const struct ChppService *newService) {
90   CHPP_DEBUG_NOT_NULL(appContext);
91   CHPP_DEBUG_NOT_NULL(serviceContext);
92   CHPP_DEBUG_NOT_NULL(serviceState);
93   CHPP_DEBUG_NOT_NULL(newService);
94 
95   const uint8_t numServices = appContext->registeredServiceCount;
96 
97   serviceState->openState = CHPP_OPEN_STATE_CLOSED;
98   serviceState->appContext = appContext;
99 
100   if (numServices >= CHPP_MAX_REGISTERED_SERVICES) {
101     CHPP_LOGE("Max services registered: # %" PRIu8, numServices);
102     serviceState->handle = CHPP_HANDLE_NONE;
103     return;
104   }
105 
106   serviceState->handle = CHPP_SERVICE_HANDLE_OF_INDEX(numServices);
107 
108   appContext->registeredServices[numServices] = newService;
109   appContext->registeredServiceContexts[numServices] = serviceContext;
110   appContext->registeredServiceCount++;
111 
112   char uuidText[CHPP_SERVICE_UUID_STRING_LEN];
113   chppUuidToStr(newService->descriptor.uuid, uuidText);
114   CHPP_LOGD("Registered service # %" PRIu8
115             " on handle %d"
116             " with name=%s, UUID=%s, version=%" PRIu8 ".%" PRIu8 ".%" PRIu16
117             ", min_len=%" PRIuSIZE " ",
118             numServices, serviceState->handle, newService->descriptor.name,
119             uuidText, newService->descriptor.version.major,
120             newService->descriptor.version.minor,
121             newService->descriptor.version.patch, newService->minLength);
122 
123   return;
124 }
125 
chppAllocServiceNotification(size_t len)126 struct ChppAppHeader *chppAllocServiceNotification(size_t len) {
127   CHPP_ASSERT(len >= sizeof(struct ChppAppHeader));
128 
129   struct ChppAppHeader *result = chppMalloc(len);
130   if (result) {
131     result->handle = CHPP_HANDLE_NONE;
132     result->type = CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION;
133     result->transaction = 0;
134     result->error = CHPP_APP_ERROR_NONE;
135     result->command = CHPP_APP_COMMAND_NONE;
136   }
137   return result;
138 }
139 
chppAllocServiceResponse(const struct ChppAppHeader * requestHeader,size_t len)140 struct ChppAppHeader *chppAllocServiceResponse(
141     const struct ChppAppHeader *requestHeader, size_t len) {
142   CHPP_ASSERT(len >= sizeof(struct ChppAppHeader));
143 
144   struct ChppAppHeader *result = chppMalloc(len);
145   if (result) {
146     *result = *requestHeader;
147     result->type = CHPP_MESSAGE_TYPE_SERVICE_RESPONSE;
148     result->error = CHPP_APP_ERROR_NONE;
149   }
150   return result;
151 }
152 
chppServiceTimestampRequest(struct ChppRequestResponseState * rRState,struct ChppAppHeader * requestHeader)153 void chppServiceTimestampRequest(struct ChppRequestResponseState *rRState,
154                                  struct ChppAppHeader *requestHeader) {
155   if (rRState->responseTimeNs == CHPP_TIME_NONE &&
156       rRState->requestTimeNs != CHPP_TIME_NONE) {
157     CHPP_LOGE("RX dupe req t=%" PRIu64,
158               rRState->requestTimeNs / CHPP_NSEC_PER_MSEC);
159   }
160   rRState->requestTimeNs = chppGetCurrentTimeNs();
161   rRState->responseTimeNs = CHPP_TIME_NONE;
162   rRState->transaction = requestHeader->transaction;
163 }
164 
chppServiceTimestampResponse(struct ChppRequestResponseState * rRState)165 uint64_t chppServiceTimestampResponse(
166     struct ChppRequestResponseState *rRState) {
167   uint64_t previousResponseTime = rRState->responseTimeNs;
168   rRState->responseTimeNs = chppGetCurrentTimeNs();
169   return previousResponseTime;
170 }
171 
chppSendTimestampedResponseOrFail(struct ChppServiceState * serviceState,struct ChppRequestResponseState * rRState,void * buf,size_t len)172 bool chppSendTimestampedResponseOrFail(struct ChppServiceState *serviceState,
173                                        struct ChppRequestResponseState *rRState,
174                                        void *buf, size_t len) {
175   uint64_t previousResponseTime = chppServiceTimestampResponse(rRState);
176 
177   if (rRState->requestTimeNs == CHPP_TIME_NONE) {
178     CHPP_LOGE("TX response w/ no req t=%" PRIu64,
179               rRState->responseTimeNs / CHPP_NSEC_PER_MSEC);
180 
181   } else if (previousResponseTime != CHPP_TIME_NONE) {
182     CHPP_LOGW("TX additional response t=%" PRIu64 " for req t=%" PRIu64,
183               rRState->responseTimeNs / CHPP_NSEC_PER_MSEC,
184               rRState->requestTimeNs / CHPP_NSEC_PER_MSEC);
185 
186   } else {
187     CHPP_LOGD("Sending initial response at t=%" PRIu64
188               " for request at t=%" PRIu64 " (RTT=%" PRIu64 ")",
189               rRState->responseTimeNs / CHPP_NSEC_PER_MSEC,
190               rRState->requestTimeNs / CHPP_NSEC_PER_MSEC,
191               (rRState->responseTimeNs - rRState->requestTimeNs) /
192                   CHPP_NSEC_PER_MSEC);
193   }
194 
195   return chppEnqueueTxDatagramOrFail(serviceState->appContext->transportContext,
196                                      buf, len);
197 }
198