46d90b5bd29eb752d8c21ad0eafe6271cf7cb762
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_encoder.c
1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491                                                                            */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG.                              */
4 /*                                                                                                */
5 /* This program is free software: you can redistribute it and/or modify                           */
6 /* it under the terms of the GNU General Public License as published by                           */
7 /* the Free Software Foundation, either version 2 of the License, or                              */
8 /* (at your option) any later version.                                                            */
9 /*                                                                                                */
10 /* This program is distributed in the hope that it will be useful,                                */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of                                 */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                  */
13 /* GNU General Public License for more details.                                                   */
14 /*                                                                                                */
15 /* You should have received a copy of the GNU General Public License                              */
16 /* along with this program.  If not, see <http://www.gnu.org/licenses/>.                          */
17 /*                                                                                                */
18 /* You may also obtain this software under a propriety license from Microchip.                    */
19 /* Please contact Microchip for further information.                                              */
20 /*------------------------------------------------------------------------------------------------*/
21
22
23 /*!
24  * \file
25  * \brief Implementation of message encoder
26  *
27  * \cond UCS_INTERNAL_DOC
28  * \addtogroup  G_ENCODER
29  * @{
30  */
31
32 /*------------------------------------------------------------------------------------------------*/
33 /* Includes                                                                                       */
34 /*------------------------------------------------------------------------------------------------*/
35 #include "ucs_encoder.h"
36 #include "ucs_misc.h"
37
38 /*------------------------------------------------------------------------------------------------*/
39 /* Constants                                                                                      */
40 /*------------------------------------------------------------------------------------------------*/
41 #define ENC_LLR_TIME_DEFAULT  11U /*! \brief Default LLR time required to transmit valid messages
42                                    *         with ContentType 0x81
43                                    */
44
45 /*------------------------------------------------------------------------------------------------*/
46 /* Internal prototypes                                                                            */
47 /*------------------------------------------------------------------------------------------------*/
48 static void    Enc_Encode_00(Msg_MostTel_t *tel_ptr, uint8_t header[]);
49 static void    Enc_Decode_00(Msg_MostTel_t *tel_ptr, uint8_t header[]);
50
51 static void    Enc_Encode_80(Msg_MostTel_t *tel_ptr, uint8_t header[]);
52 static void    Enc_Decode_80(Msg_MostTel_t *tel_ptr, uint8_t header[]);
53
54 static void    Enc_Encode_81(Msg_MostTel_t *tel_ptr, uint8_t header[]);
55 static void    Enc_Decode_81(Msg_MostTel_t *tel_ptr, uint8_t header[]);
56
57 /*------------------------------------------------------------------------------------------------*/
58 /* Implementation                                                                                 */
59 /*------------------------------------------------------------------------------------------------*/
60 /*! \brief      Retrieves the interface of a specific encoder
61  *  \details    Creates all encoder interfaces as singletons
62  *  \param      type    Specifies the type of encoder to retrieve
63  *  \return     The desired interface to the specified encoder 
64  */
65 IEncoder *Enc_GetEncoder(Enc_MsgContent_t type)
66 {
67     static IEncoder enc_content_00 = {ENC_CONTENT_00, 8U, 12U, &Enc_Encode_00, &Enc_Decode_00};
68     static IEncoder enc_content_80 = {ENC_CONTENT_80, 6U, 11U, &Enc_Encode_80, &Enc_Decode_80};
69     static IEncoder enc_content_81 = {ENC_CONTENT_81, 6U, 13U, &Enc_Encode_81, &Enc_Decode_81};
70     IEncoder *encoder_ptr = NULL;
71
72     switch (type)
73     {
74         case ENC_CONTENT_00:
75             encoder_ptr = &enc_content_00;
76             break;
77         case ENC_CONTENT_80:
78             encoder_ptr = &enc_content_80;
79             break;
80         case ENC_CONTENT_81:
81             encoder_ptr = &enc_content_81;
82             break;
83         default:
84             encoder_ptr = NULL;
85             break;
86     }
87
88     return encoder_ptr;
89 }
90
91 /*------------------------------------------------------------------------------------------------*/
92 /* Content type "00"                                                                               */
93 /*------------------------------------------------------------------------------------------------*/
94 /*! \brief  Encodes a message telegram to the "ContentType 0x00" MOST message header 
95  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
96  *  \param  header      The header buffer 
97  */
98 static void Enc_Encode_00(Msg_MostTel_t *tel_ptr, uint8_t header[])
99 {
100     header[0]  = MISC_HB(tel_ptr->source_addr);
101     header[1]  = MISC_LB(tel_ptr->source_addr);
102     header[2]  = MISC_HB(tel_ptr->destination_addr);
103     header[3]  = MISC_LB(tel_ptr->destination_addr);
104
105     header[4]  = tel_ptr->id.fblock_id;
106     header[5]  = tel_ptr->id.instance_id;
107
108     header[6]  = MISC_HB(tel_ptr->id.function_id);
109     header[7]  = MISC_LB(tel_ptr->id.function_id);
110
111     header[8]  = (uint8_t)(tel_ptr->tel.tel_id << 4) | (uint8_t)((uint8_t)tel_ptr->id.op_type & 0xFU);
112     header[9]  = tel_ptr->opts.llrbc;
113
114     header[10] = tel_ptr->tel.tel_cnt;
115     header[11] = tel_ptr->tel.tel_len;
116 }
117
118 /*! \brief  Decodes a "ContentType 0x00" MOST message header to a message telegram structure 
119  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
120  *  \param  header      The header buffer 
121  */
122 static void Enc_Decode_00(Msg_MostTel_t *tel_ptr, uint8_t header[])
123 {
124     tel_ptr->source_addr        = (uint16_t)((uint16_t)header[0] << 8) | (uint16_t)header[1];
125     tel_ptr->destination_addr   = (uint16_t)((uint16_t)header[2] << 8) | (uint16_t)header[3];
126
127     tel_ptr->id.fblock_id       = header[4];
128     tel_ptr->id.instance_id     = header[5];
129
130     tel_ptr->id.function_id     = (uint16_t)((uint16_t)header[6] << 8) | (uint16_t)header[7];
131
132     tel_ptr->tel.tel_id         = header[8] >> 4;                       /* high nibble: TelId */
133     tel_ptr->id.op_type         = (Ucs_OpType_t)(header[8] & 0x0FU);    /* low nibble: OPType */
134
135     tel_ptr->opts.llrbc         = header[9];
136     tel_ptr->tel.tel_cnt        = header[10];
137     tel_ptr->tel.tel_len        = header[11];
138
139     tel_ptr->tel.tel_data_ptr   = &header[12];
140 }
141
142 /*------------------------------------------------------------------------------------------------*/
143 /* Content type "0x80"                                                                              */
144 /*------------------------------------------------------------------------------------------------*/
145 /*! \brief  Encodes a message telegram to the "ContentType 0x80" MOST message header 
146  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
147  *  \param  header      The header buffer 
148  */
149 static void Enc_Encode_80(Msg_MostTel_t *tel_ptr, uint8_t header[])
150 {             /* high nibble: TelId                    low nibble: OPType */
151     header[0]  = (uint8_t)(tel_ptr->tel.tel_id << 4) | (uint8_t)((uint8_t)tel_ptr->id.op_type & 0xFU);
152     header[1]  = tel_ptr->tel.tel_cnt;
153     header[2]  = tel_ptr->tel.tel_len;
154
155     header[3]  = MISC_HB(tel_ptr->id.function_id);
156     header[4]  = MISC_LB(tel_ptr->id.function_id);
157
158     header[5]  = MISC_HB(tel_ptr->source_addr);
159     header[6]  = MISC_LB(tel_ptr->source_addr);
160
161     header[7]  = MISC_HB(tel_ptr->destination_addr);
162     header[8]  = MISC_LB(tel_ptr->destination_addr);
163
164     header[9]  = tel_ptr->id.fblock_id;
165     header[10] = tel_ptr->id.instance_id;
166 }
167
168 /*! \brief  Decodes a "ContentType 0x80" MOST message header to a message telegram structure 
169  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
170  *  \param  header      The header buffer 
171  */
172 static void Enc_Decode_80(Msg_MostTel_t *tel_ptr, uint8_t header[])
173 {
174     tel_ptr->tel.tel_id         = header[0] >> 4;                       /* high nibble: TelId */
175     tel_ptr->id.op_type         = (Ucs_OpType_t)(header[0] & 0x0FU);    /* low nibble: OPType */
176
177     tel_ptr->tel.tel_cnt        = header[1];
178     tel_ptr->tel.tel_len        = header[2];
179
180     tel_ptr->id.function_id     = (uint16_t)((uint16_t)header[3] << 8) | (uint16_t)header[4];
181
182     tel_ptr->source_addr        = (uint16_t)((uint16_t)header[5] << 8) | (uint16_t)header[6];
183     tel_ptr->destination_addr   = (uint16_t)((uint16_t)header[7] << 8) | (uint16_t)header[8];
184
185     tel_ptr->id.fblock_id       = header[9];
186     tel_ptr->id.instance_id     = header[10];
187
188     tel_ptr->tel.tel_data_ptr   = &header[11];
189 }
190
191 /*------------------------------------------------------------------------------------------------*/
192 /* Content type "0x81"                                                                              */
193 /*------------------------------------------------------------------------------------------------*/
194 /*! \brief  Encodes a message telegram to the "ContentType 0x81" MOST message header 
195  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
196  *  \param  header      The header buffer 
197  */
198 static void Enc_Encode_81(Msg_MostTel_t *tel_ptr, uint8_t header[])
199 {
200     header[0]  = tel_ptr->opts.llrbc;
201     header[1]  = ENC_LLR_TIME_DEFAULT; 
202     /*           high nibble: TelId                    low nibble: OPType */
203     header[2]  = (uint8_t)(tel_ptr->tel.tel_id << 4) | (uint8_t)((uint8_t)tel_ptr->id.op_type & 0xFU);
204     header[3]  = tel_ptr->tel.tel_cnt;
205     header[4]  = tel_ptr->tel.tel_len;
206
207     header[5]  = MISC_HB(tel_ptr->id.function_id);
208     header[6]  = MISC_LB(tel_ptr->id.function_id);
209
210     header[7]  = MISC_HB(tel_ptr->source_addr);
211     header[8]  = MISC_LB(tel_ptr->source_addr);
212
213     header[9]  = MISC_HB(tel_ptr->destination_addr);
214     header[10] = MISC_LB(tel_ptr->destination_addr);
215
216     header[11] = tel_ptr->id.fblock_id;
217     header[12] = tel_ptr->id.instance_id;
218 }
219
220 /*! \brief  Decodes a "ContentType 0x81" MOST message header to a message telegram structure 
221  *  \param  tel_ptr     Reference to the Msg_MostTel_t structure 
222  *  \param  header      The header buffer 
223  */
224 static void Enc_Decode_81(Msg_MostTel_t *tel_ptr, uint8_t header[])
225 {
226     tel_ptr->opts.llrbc         = header[0];
227
228     tel_ptr->tel.tel_id         = header[2] >> 4;                       /* high nibble: TelId */
229     tel_ptr->id.op_type         = (Ucs_OpType_t)(header[2] & 0x0FU);    /* low nibble: OPType */
230
231     tel_ptr->tel.tel_cnt        = header[3];
232     tel_ptr->tel.tel_len        = header[4];
233
234     tel_ptr->id.function_id     = (uint16_t)((uint16_t)header[5] << 8) | (uint16_t)header[6];
235
236     tel_ptr->source_addr        = (uint16_t)((uint16_t)header[7] << 8) | (uint16_t)header[8];
237     tel_ptr->destination_addr   = (uint16_t)((uint16_t)header[9] << 8) | (uint16_t)header[10];
238
239     tel_ptr->id.fblock_id       = header[11];
240     tel_ptr->id.instance_id     = header[12];
241
242     tel_ptr->tel.tel_data_ptr   = &header[13];
243 }
244
245 /*!
246  * @}
247  * \endcond
248  */
249
250 /*------------------------------------------------------------------------------------------------*/
251 /* End of file                                                                                    */
252 /*------------------------------------------------------------------------------------------------*/
253