• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "can/can_core.h"
10 #include "can/can_mail.h"
11 #include "can/can_msg.h"
12 
CanCntlrLock(struct CanCntlr * cntlr)13 static int32_t CanCntlrLock(struct CanCntlr *cntlr)
14 {
15     if (cntlr->ops != NULL && cntlr->ops->lock != NULL) {
16         return cntlr->ops->lock(cntlr);
17     } else {
18         return OsalMutexLock(&cntlr->lock);
19     }
20 }
21 
CanCntlrUnlock(struct CanCntlr * cntlr)22 static void CanCntlrUnlock(struct CanCntlr *cntlr)
23 {
24     if (cntlr->ops != NULL && cntlr->ops->unlock != NULL) {
25         cntlr->ops->unlock(cntlr);
26     } else {
27         (void)OsalMutexUnlock(&cntlr->lock);
28     }
29 }
30 
CanCntlrWriteMsg(struct CanCntlr * cntlr,const struct CanMsg * msg)31 int32_t CanCntlrWriteMsg(struct CanCntlr *cntlr, const struct CanMsg *msg)
32 {
33     int32_t ret;
34 
35     if (cntlr == NULL) {
36         HDF_LOGE("CanCntlrWriteMsg: cntlr is null!");
37         return HDF_ERR_INVALID_OBJECT;
38     }
39     if (cntlr->ops == NULL || cntlr->ops->sendMsg == NULL) {
40         HDF_LOGE("CanCntlrWriteMsg: ops or sendMsg is null!");
41         return HDF_ERR_NOT_SUPPORT;
42     }
43 
44     if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
45         HDF_LOGE("CanCntlrWriteMsg: can cntlr lock fail!");
46         return ret;
47     }
48     ret = cntlr->ops->sendMsg(cntlr, msg);
49     CanCntlrUnlock(cntlr);
50     return ret;
51 }
52 
CanCntlrSetCfg(struct CanCntlr * cntlr,const struct CanConfig * cfg)53 int32_t CanCntlrSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg)
54 {
55     int32_t ret;
56 
57     if (cntlr == NULL) {
58         HDF_LOGE("CanCntlrSetCfg: cntlr is null!");
59         return HDF_ERR_INVALID_OBJECT;
60     }
61     if (cntlr->ops == NULL || cntlr->ops->setCfg == NULL) {
62         HDF_LOGE("CanCntlrSetCfg: ops or setCfg is null!");
63         return HDF_ERR_NOT_SUPPORT;
64     }
65 
66     if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
67         HDF_LOGE("CanCntlrSetCfg: can cntlr lock fail!");
68         return ret;
69     }
70     ret = cntlr->ops->setCfg(cntlr, cfg);
71     CanCntlrUnlock(cntlr);
72     return ret;
73 }
74 
CanCntlrGetCfg(struct CanCntlr * cntlr,struct CanConfig * cfg)75 int32_t CanCntlrGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg)
76 {
77     int32_t ret;
78 
79     if (cntlr == NULL) {
80         HDF_LOGE("CanCntlrGetCfg: cntlr is null!");
81         return HDF_ERR_INVALID_OBJECT;
82     }
83     if (cntlr->ops == NULL || cntlr->ops->getCfg == NULL) {
84         HDF_LOGE("CanCntlrGetCfg: ops or setCfg is null!");
85         return HDF_ERR_NOT_SUPPORT;
86     }
87 
88     if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
89         HDF_LOGE("CanCntlrGetCfg: can cntlr lock fail!");
90         return ret;
91     }
92     ret = cntlr->ops->getCfg(cntlr, cfg);
93     CanCntlrUnlock(cntlr);
94     return ret;
95 }
96 
CanCntlrGetState(struct CanCntlr * cntlr)97 int32_t CanCntlrGetState(struct CanCntlr *cntlr)
98 {
99     int32_t ret;
100 
101     if (cntlr == NULL) {
102         HDF_LOGE("CanCntlrGetState: cntlr is null!");
103         return HDF_ERR_INVALID_OBJECT;
104     }
105     if (cntlr->ops == NULL || cntlr->ops->getState == NULL) {
106         HDF_LOGE("CanCntlrGetState: ops or setCfg is null!");
107         return HDF_ERR_NOT_SUPPORT;
108     }
109 
110     if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
111         HDF_LOGE("CanCntlrGetState: can cntlr lock fail!");
112         return ret;
113     }
114     ret = cntlr->ops->getState(cntlr);
115     CanCntlrUnlock(cntlr);
116     return ret;
117 }
118 
CanCntlrAddRxBox(struct CanCntlr * cntlr,struct CanRxBox * rxBox)119 int32_t CanCntlrAddRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox)
120 {
121     if (cntlr == NULL) {
122         HDF_LOGE("CanCntlrAddRxBox: cntlr is null!");
123         return HDF_ERR_INVALID_OBJECT;
124     }
125     if (rxBox == NULL) {
126         HDF_LOGE("CanCntlrAddRxBox: rxBox is null!");
127         return HDF_ERR_INVALID_PARAM;
128     }
129     (void)OsalMutexLock(&cntlr->rboxListLock);
130     DListInsertTail(&rxBox->node, &cntlr->rxBoxList);
131     (void)OsalMutexUnlock(&cntlr->rboxListLock);
132     return HDF_SUCCESS;
133 }
134 
CanCntlrDelRxBox(struct CanCntlr * cntlr,struct CanRxBox * rxBox)135 int32_t CanCntlrDelRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox)
136 {
137     struct CanRxBox *tmp = NULL;
138     struct CanRxBox *toRmv = NULL;
139 
140     if (cntlr == NULL) {
141         HDF_LOGE("CanCntlrDelRxBox: cntlr is null!");
142         return HDF_ERR_INVALID_OBJECT;
143     }
144     if (rxBox == NULL) {
145         HDF_LOGE("CanCntlrDelRxBox: rxBox is null!");
146         return HDF_ERR_INVALID_PARAM;
147     }
148     (void)OsalMutexLock(&cntlr->rboxListLock);
149     DLIST_FOR_EACH_ENTRY_SAFE(toRmv, tmp, &cntlr->rxBoxList, struct CanRxBox, node) {
150         if (toRmv == rxBox) {
151             DListRemove(&toRmv->node);
152             (void)OsalMutexUnlock(&cntlr->rboxListLock);
153             return HDF_SUCCESS;
154         }
155     }
156     (void)OsalMutexUnlock(&cntlr->rboxListLock);
157     HDF_LOGE("CanCntlrDelRxBox: del rxBox is not support!");
158     return HDF_ERR_NOT_SUPPORT;
159 }
160 
CanCntlrMsgDispatch(struct CanCntlr * cntlr,struct CanMsg * msg)161 static int32_t CanCntlrMsgDispatch(struct CanCntlr *cntlr, struct CanMsg *msg)
162 {
163     struct CanRxBox *rxBox = NULL;
164 
165     (void)OsalMutexLock(&cntlr->rboxListLock);
166     DLIST_FOR_EACH_ENTRY(rxBox, &cntlr->rxBoxList, struct CanRxBox, node) {
167         (void)CanRxBoxAddMsg(rxBox, msg);
168     }
169     (void)OsalMutexUnlock(&cntlr->rboxListLock);
170     CanMsgPut(msg);
171 
172     return HDF_SUCCESS;
173 }
174 
CanCntlrOnNewMsg(struct CanCntlr * cntlr,const struct CanMsg * msg)175 int32_t CanCntlrOnNewMsg(struct CanCntlr *cntlr, const struct CanMsg *msg)
176 {
177     struct CanMsg *copy = NULL;
178 
179     if (cntlr == NULL) {
180         HDF_LOGE("CanCntlrOnNewMsg: cntlr is null!");
181         return HDF_ERR_INVALID_OBJECT;
182     }
183 
184     if (msg == NULL) {
185         HDF_LOGE("CanCntlrOnNewMsg: msg is null!");
186         return HDF_ERR_INVALID_PARAM;
187     }
188 
189     copy = CanMsgPoolObtainMsg(cntlr->msgPool);
190     if (copy == NULL) {
191         HDF_LOGE("CanCntlrOnNewMsg: can msg pool obtain msg fail!");
192         return HDF_FAILURE;
193     }
194     *copy = *msg;
195 
196     return CanCntlrMsgDispatch(cntlr, copy); // gona call in thread context later ...
197 }
198 
CanCntlrOnNewMsgIrqSafe(struct CanCntlr * cntlr,const struct CanMsg * msg)199 int32_t CanCntlrOnNewMsgIrqSafe(struct CanCntlr *cntlr, const struct CanMsg *msg)
200 {
201     if (cntlr == NULL) {
202         HDF_LOGE("CanCntlrOnNewMsgIrqSafe: cntlr is null!");
203         return HDF_ERR_INVALID_OBJECT;
204     }
205 
206     if (msg == NULL) {
207         HDF_LOGE("CanCntlrOnNewMsgIrqSafe: msg is null!");
208         return HDF_ERR_INVALID_PARAM;
209     }
210 
211     if ((cntlr->threadStatus & CAN_THREAD_RUNNING) == 0 || (cntlr->threadStatus & CAN_THREAD_PENDING) != 0) {
212         HDF_LOGE("CanCntlrOnNewMsgIrqSafe: device is busy!");
213         return HDF_ERR_DEVICE_BUSY;
214     }
215     cntlr->irqMsg = msg;
216     cntlr->threadStatus |= CAN_THREAD_PENDING;
217     (void)OsalSemPost(&cntlr->sem);
218     return HDF_SUCCESS;
219 }
220