1 /*
2 * Copyright (c) 2022 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 return HDF_ERR_INVALID_OBJECT;
37 }
38 if (cntlr->ops == NULL || cntlr->ops->sendMsg == NULL) {
39 return HDF_ERR_NOT_SUPPORT;
40 }
41
42 if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
43 return ret;
44 }
45 ret = cntlr->ops->sendMsg(cntlr, msg);
46 CanCntlrUnlock(cntlr);
47 return ret;
48 }
49
CanCntlrSetCfg(struct CanCntlr * cntlr,const struct CanConfig * cfg)50 int32_t CanCntlrSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg)
51 {
52 int32_t ret;
53
54 if (cntlr == NULL) {
55 return HDF_ERR_INVALID_OBJECT;
56 }
57 if (cntlr->ops == NULL || cntlr->ops->setCfg == NULL) {
58 return HDF_ERR_NOT_SUPPORT;
59 }
60
61 if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
62 return ret;
63 }
64 ret = cntlr->ops->setCfg(cntlr, cfg);
65 CanCntlrUnlock(cntlr);
66 return ret;
67 }
68
CanCntlrGetCfg(struct CanCntlr * cntlr,struct CanConfig * cfg)69 int32_t CanCntlrGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg)
70 {
71 int32_t ret;
72
73 if (cntlr == NULL) {
74 return HDF_ERR_INVALID_OBJECT;
75 }
76 if (cntlr->ops == NULL || cntlr->ops->getCfg == NULL) {
77 return HDF_ERR_NOT_SUPPORT;
78 }
79
80 if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
81 return ret;
82 }
83 ret = cntlr->ops->getCfg(cntlr, cfg);
84 CanCntlrUnlock(cntlr);
85 return ret;
86 }
87
CanCntlrGetState(struct CanCntlr * cntlr)88 int32_t CanCntlrGetState(struct CanCntlr *cntlr)
89 {
90 int32_t ret;
91
92 if (cntlr == NULL) {
93 return HDF_ERR_INVALID_OBJECT;
94 }
95 if (cntlr->ops == NULL || cntlr->ops->getState == NULL) {
96 return HDF_ERR_NOT_SUPPORT;
97 }
98
99 if ((ret = CanCntlrLock(cntlr)) != HDF_SUCCESS) {
100 return ret;
101 }
102 ret = cntlr->ops->getState(cntlr);
103 CanCntlrUnlock(cntlr);
104 return ret;
105 }
106
CanCntlrAddRxBox(struct CanCntlr * cntlr,struct CanRxBox * rxBox)107 int32_t CanCntlrAddRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox)
108 {
109 if (cntlr == NULL) {
110 return HDF_ERR_INVALID_OBJECT;
111 }
112 if (rxBox == NULL) {
113 return HDF_ERR_INVALID_PARAM;
114 }
115 (void)OsalMutexLock(&cntlr->rboxListLock);
116 DListInsertTail(&rxBox->node, &cntlr->rxBoxList);
117 (void)OsalMutexUnlock(&cntlr->rboxListLock);
118 return HDF_SUCCESS;
119 }
120
CanCntlrDelRxBox(struct CanCntlr * cntlr,struct CanRxBox * rxBox)121 int32_t CanCntlrDelRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox)
122 {
123 struct CanRxBox *tmp = NULL;
124 struct CanRxBox *toRmv = NULL;
125
126 if (cntlr == NULL) {
127 return HDF_ERR_INVALID_OBJECT;
128 }
129 if (rxBox == NULL) {
130 return HDF_ERR_INVALID_PARAM;
131 }
132 (void)OsalMutexLock(&cntlr->rboxListLock);
133 DLIST_FOR_EACH_ENTRY_SAFE(toRmv, tmp, &cntlr->rxBoxList, struct CanRxBox, node) {
134 if (toRmv == rxBox) {
135 DListRemove(&toRmv->node);
136 (void)OsalMutexUnlock(&cntlr->rboxListLock);
137 return HDF_SUCCESS;
138 }
139 }
140 (void)OsalMutexUnlock(&cntlr->rboxListLock);
141 return HDF_ERR_NOT_SUPPORT;
142 }
143
CanCntlrMsgDispatch(struct CanCntlr * cntlr,struct CanMsg * msg)144 static int32_t CanCntlrMsgDispatch(struct CanCntlr *cntlr, struct CanMsg *msg)
145 {
146 struct CanRxBox *rxBox = NULL;
147
148 (void)OsalMutexLock(&cntlr->rboxListLock);
149 DLIST_FOR_EACH_ENTRY(rxBox, &cntlr->rxBoxList, struct CanRxBox, node) {
150 (void)CanRxBoxAddMsg(rxBox, msg);
151 }
152 (void)OsalMutexUnlock(&cntlr->rboxListLock);
153 CanMsgPut(msg);
154
155 return HDF_SUCCESS;
156 }
157
CanCntlrOnNewMsg(struct CanCntlr * cntlr,const struct CanMsg * msg)158 int32_t CanCntlrOnNewMsg(struct CanCntlr *cntlr, const struct CanMsg *msg)
159 {
160 struct CanMsg *copy = NULL;
161
162 if (cntlr == NULL) {
163 return HDF_ERR_INVALID_OBJECT;
164 }
165
166 if (msg == NULL) {
167 return HDF_ERR_INVALID_PARAM;
168 }
169
170 copy = CanMsgPoolObtainMsg(cntlr->msgPool);
171 if (copy == NULL) {
172 return HDF_FAILURE;
173 }
174 *copy = *msg;
175
176 return CanCntlrMsgDispatch(cntlr, copy); // gona call in thread context later ...
177 }
178