Annotation of libaitpelco/src/aitpelco.c, revision 1.4
1.1 misho 1: /*************************************************************************
2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.4 ! misho 6: * $Id: aitpelco.c,v 1.3.4.1 2013/05/26 20:39:14 misho Exp $
1.1 misho 7: *
1.2 misho 8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.4 ! misho 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
1.2 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
1.1 misho 46: #include "global.h"
47: #include "aitpelco.h"
48:
49:
50: static int pelco_Errno;
51: static char pelco_Error[STRSIZ];
52:
53:
54: //
55: // Error maintenance functions ...
56: //
57:
58: // pelco_GetErrno() Get error code of last operation
1.4 ! misho 59: int
1.2 misho 60: pelco_GetErrno()
1.1 misho 61: {
62: return pelco_Errno;
63: }
64:
65: // pelco_GetError() Get error text of last operation
1.4 ! misho 66: const char *
1.2 misho 67: pelco_GetError()
1.1 misho 68: {
69: return pelco_Error;
70: }
71:
72: // pelco_SetErr() Set error to variables for internal use!!!
1.4 ! misho 73: void
1.2 misho 74: pelcoSetErr(int eno, char *estr, ...)
1.1 misho 75: {
76: va_list lst;
77:
78: pelco_Errno = eno;
1.3 misho 79: memset(pelco_Error, 0, sizeof pelco_Error);
1.1 misho 80: va_start(lst, estr);
1.3 misho 81: vsnprintf(pelco_Error, sizeof pelco_Error, estr, lst);
1.1 misho 82: va_end(lst);
83: }
84:
85: // ----------------------------------------------------------
86:
87: /*
88: * pelcoOpen() Open packet record for camera number with Pelco version D/P
89: * @pelcoVer = Pelco protocol version Dd | Pp
90: * @camNo = Packet for camera number address
91: * return: NULL error, !=NULL ok, allocated memory for packet
92: */
1.4 ! misho 93: void *
1.2 misho 94: pelcoOpen(u_char pelcoVer, u_char camNo)
1.1 misho 95: {
96: pelco_d_t *pd;
97: pelco_p_t *pp;
98: void *p = NULL;
99:
100: switch (pelcoVer) {
101: case 'D':
102: case 'd':
103: if (camNo < FIRST_CAM_D) {
1.2 misho 104: pelcoSetErr(ENOEXEC, "unsupported camera number %d!\n", camNo);
1.1 misho 105: return NULL;
106: }
107:
108: pd = malloc(sizeof(pelco_d_t));
109: if (!pd) {
110: SETERR;
111: return NULL;
112: } else
113: memset(pd, 0, sizeof(pelco_d_t));
114:
115: pd->d_sync = VER_D_SYNC;
116: pd->d_cam = camNo;
117:
118: p = pd;
119: break;
120: case 'P':
121: case 'p':
122: pp = malloc(sizeof(pelco_p_t));
123: if (!pp) {
124: SETERR;
125: return NULL;
126: } else
127: memset(pp, 0, sizeof(pelco_p_t));
128:
129: pp->p_stx = VER_P_STX;
130: pp->p_cam = !camNo ? camNo : camNo - 1;
131: pp->p_etx = VER_P_ETX;
132:
133: p = pp;
134: break;
135: default:
1.2 misho 136: pelcoSetErr(ENOEXEC, "unsupported Pelco protocol version!\n");
1.1 misho 137: }
138:
139: return p;
140: }
141:
142: /*
143: * pelcoClose() Close packet record and free memory
144: * @p = Packet structure for close
145: */
1.4 ! misho 146: void
1.2 misho 147: pelcoClose(void * __restrict p)
1.1 misho 148: {
149: if (p)
150: free(p);
151: }
152:
1.2 misho 153: /*
154: * pelcoLoad() Load packet from input buffer
155: * @buffer = Pelco packet from input buffer
156: * return: NULL error, !=NULL ok, allocated memory for packet
157: */
1.4 ! misho 158: void *
1.2 misho 159: pelcoLoad(u_char *buffer)
160: {
161: pelco_d_t *pd;
162: pelco_p_t *pp;
163: void *p = NULL;
164:
165: if (!buffer || !*buffer) {
166: pelcoSetErr(EINVAL, "invalid argument!\n");
167: return NULL;
168: }
169:
170: switch (pelco_GetVersion(buffer)) {
171: case 'd':
172: if (pelco_GetCamNo(buffer) < FIRST_CAM_D) {
173: pelcoSetErr(ENOEXEC, "unsupported camera number %d!\n",
174: pelco_GetCamNo(buffer));
175: return NULL;
176: }
177:
178: pd = malloc(sizeof(pelco_d_t));
179: if (!pd) {
180: SETERR;
181: return NULL;
182: } else
183: memcpy(pd, buffer, sizeof(pelco_d_t));
184:
185: p = pd;
186: break;
187: case 'p':
188: pp = malloc(sizeof(pelco_p_t));
189: if (!pp) {
190: SETERR;
191: return NULL;
192: } else
193: memcpy(pp, buffer, sizeof(pelco_p_t));
194:
195: p = pp;
196: break;
197: default:
198: pelcoSetErr(ENOEXEC, "unsupported Pelco protocol version!\n");
199: }
200:
201: return p;
202: }
1.1 misho 203:
204: /*
205: * pelcoAddCmdData() Add commands and datas for already opened packet
206: * @p = Input Packet structure
207: * @cmd[2] = Input Commands 1 & 2
208: * @data[2] = Input Data for commands 1 & 2
209: * return: 0xFF - error, 0 - ok
210: */
1.4 ! misho 211: u_char
1.2 misho 212: pelcoAddCmdData(void * __restrict p, u_char * __restrict cmd, u_char * __restrict data)
1.1 misho 213: {
214: u_char ret = 0;
215: pelco_d_t *pd = (pelco_d_t *) p;
216: pelco_p_t *pp = (pelco_p_t *) p;
217: u_char *ptr = p;
218:
1.2 misho 219: if (!p || !*ptr) {
220: pelcoSetErr(EINVAL, "invalid argument!\n");
1.1 misho 221: return 0xFF;
222: }
223:
224: switch (ptr[0]) {
225: case VER_D_SYNC:
226: if (ptr[1] < FIRST_CAM_D) {
1.2 misho 227: pelcoSetErr(ENOEXEC, "unsupported camera number %d!\n", ptr[1]);
1.1 misho 228: return 0xFF;
229: }
230:
231: if (cmd)
232: memcpy(&pd->d_cmd1, cmd, 2);
233: if (data)
234: memcpy(&pd->d_data, data, 2);
235: pd->d_crc = crcPelco('d', p);
236: break;
237: case VER_P_STX:
238: if (VER_P_ETX != ptr[6]) {
1.2 misho 239: pelcoSetErr(ENOEXEC, "Broken Pelco P packet!\n");
1.1 misho 240: return 0xFF;
241: }
242:
243: if (cmd)
244: memcpy(&pp->p_cmd1, cmd, 2);
245: if (data)
246: memcpy(&pp->p_data, data, 2);
247: pp->p_crc = crcPelco('p', p);
248: break;
249: default:
1.2 misho 250: pelcoSetErr(ENOEXEC, "Invalid protocol!\n");
1.1 misho 251: return 0xFF;
252: }
253:
254: return ret;
255: }
1.2 misho 256:
257: /*
258: * pelcoGetCmdData() Get from packet commands and datas with verify packet
259: * @p = Input Packet structure
260: * @cmd[2] = Output Commands 1 & 2
261: * @data[2] = Output Data for commands 1 & 2
262: * return: 'd' - PelcoD, 'p' - PelcoP, 0 - unknown or bad packet
263: */
1.4 ! misho 264: u_char
1.2 misho 265: pelcoGetCmdData(void * __restrict p, u_char * __restrict cmd, u_char * __restrict data)
266: {
267: return pelco_GetCamCmdData(p, NULL, cmd, data);
268: }
269:
270: /*
271: * pelcoChkSum() Check ot Correct check sum in packet
272: * @p = Input Packet structure
273: * @correct = Calculate new check sum if incorrect !=0, if ==0 only check
274: * return: 0xFF - bad packet, 1 invalid check sum, 0 check sum is correct.
275: */
1.4 ! misho 276: u_char
1.2 misho 277: pelcoChkSum(void * __restrict p, u_char correct)
278: {
279: u_char sum, *ptr = p;
280: pelco_d_t *pd = (pelco_d_t *) p;
281: pelco_p_t *pp = (pelco_p_t *) p;
282:
283: if (!p || !*ptr) {
284: pelcoSetErr(EINVAL, "invalid argument!\n");
285: return 0xFF;
286: }
287:
288: switch (ptr[0]) {
289: case VER_D_SYNC:
290: if (ptr[1] < FIRST_CAM_D) {
291: pelcoSetErr(ENOEXEC, "unsupported camera number %d!\n", ptr[1]);
292: return 0xFF;
293: }
294:
295: sum = crcPelco('d', p);
296: if (correct)
297: pd->d_crc = sum;
298: break;
299: case VER_P_STX:
300: if (VER_P_ETX != ptr[6]) {
301: pelcoSetErr(ENOEXEC, "Broken Pelco P packet!\n");
302: return 0xFF;
303: }
304:
305: sum = crcPelco('p', p);
306: if (correct)
307: pp->p_crc = sum;
308: break;
309: default:
310: pelcoSetErr(ENOEXEC, "Invalid protocol!\n");
311: return 0xFF;
312: }
313:
314: return sum;
315: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>