1 /* (c) 2006 by Marcin Wiacek */
2 
3 #include "../../gsmstate.h"
4 
5 #if defined(GSM_ENABLE_BLUEGNAPBUS) || defined(GSM_ENABLE_IRDAGNAPBUS)
6 
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 
11 #include "../../gsmcomon.h"
12 #include "gnapbus.h"
13 
GNAPBUS_WriteMessage(GSM_StateMachine * s,unsigned const char * MsgBuffer,size_t MsgLength,int MsgType)14 static GSM_Error GNAPBUS_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer,
15 				    size_t MsgLength, int MsgType)
16 {
17 	unsigned char	*buffer=NULL;
18 	int		sent=0,length=0,i=0;
19 	unsigned char	checksum=0;
20 
21 	GSM_DumpMessageBinary(s, MsgBuffer, MsgLength, MsgType);
22 
23 	buffer = (unsigned char *)malloc(MsgLength + 10);
24 
25 	buffer[0] = GNAPBUS_FRAME_ID,
26 	buffer[1] = 0x00;
27 	buffer[2] = MsgLength / 256;
28 	buffer[3] = MsgLength % 256;
29 	buffer[4] = MsgType;
30 	buffer[5] = 0x00;
31 	memcpy(buffer + 6, MsgBuffer, MsgLength);
32 	length = MsgLength+6;
33 
34 	if (MsgLength & 1) buffer[length++] = 0x00;
35 	/* Odd messages require additional 0x00 byte */
36 /* 	if (MsgLength % 2) buffer[length++] = 0x00; */
37 
38 	checksum 	= 0;
39 	for (i = 0; i < length; i+=2) checksum ^= buffer[i];
40 	buffer[length++] 	= checksum;
41 
42 	checksum 	= 0;
43 	for (i = 1; i < length; i+=2) checksum ^= buffer[i];
44 	buffer[length++] 	= checksum;
45 
46 /* 	GSM_DumpMessageText(s, buffer, length, MsgType); */
47 	GSM_DumpMessageText(s, MsgBuffer, MsgLength, MsgType);
48 
49 	/* Sending to phone */
50 	sent = s->Device.Functions->WriteDevice(s,buffer,length);
51 	free(buffer);
52 	buffer=NULL;
53 
54 	if (sent!=length) {
55 		return ERR_DEVICEWRITEERROR;
56 	}
57 	return ERR_NONE;
58 }
59 
GNAPBUS_StateMachine(GSM_StateMachine * s,unsigned char rx_char)60 static GSM_Error GNAPBUS_StateMachine(GSM_StateMachine *s, unsigned char rx_char)
61 {
62 	GSM_Protocol_GNAPBUSData *d = &s->Protocol.Data.GNAPBUS;
63 
64 /* printf("%02x ",rx_char); */
65 /* fflush(stdout); */
66 	/* XOR the byte with the earlier checksum */
67 	d->Msg.CheckSum[d->Msg.Count & 1] ^= rx_char;
68 
69 	switch (d->MsgRXState) {
70 	case RX_Sync:
71 		if (rx_char == GNAPBUS_FRAME_ID) {
72 			d->MsgRXState = RX_GetDestination;
73 			d->Msg.Count = 0;
74 			d->Msg.Length = 0;
75 			d->Msg.CheckSum[0] = rx_char;
76 			d->Msg.CheckSum[1] = 0;
77 		} else smprintf(s,"Sync error: %02x\n",rx_char);
78 		break;
79 	case RX_GetDestination:
80 		d->MsgRXState = RX_GetLength1;
81 		break;
82 	case RX_GetLength1:
83 		d->MsgRXState = RX_GetLength2;
84 		d->Msg.Length = rx_char << 8;
85 		break;
86 	case RX_GetLength2:
87 		d->MsgRXState = RX_GetType;
88 		d->Msg.Length += rx_char;
89 		d->Msg.Buffer 	= (unsigned char *)malloc(d->Msg.Length+3);
90 		break;
91 	case RX_GetType:
92 		d->MsgRXState = RX_GetSource;
93 		d->Msg.Type = rx_char;
94 		break;
95 	case RX_GetSource:
96 		d->MsgRXState = RX_GetMessage;
97 		break;
98 	case RX_GetMessage:
99 		d->Msg.Buffer[d->Msg.Count] = rx_char;
100 		d->Msg.Count++;
101 
102 		if (d->Msg.Count != ((d->Msg.Length+3)& ~1)) return ERR_NONE;
103 
104 /* 	GSM_DumpMessageText(s, d->Msg.Buffer, d->Msg.Count, d->Msg.Type); */
105 /* printf("\n%02x %02x\n",d->Msg.CheckSum[0],d->Msg.CheckSum[1]); */
106 		/* Checksum is incorrect */
107 		if (d->Msg.CheckSum[0] != d->Msg.CheckSum[1]) {
108 			if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR ||
109 			    s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) {
110 				smprintf(s,"[ERROR: checksum]\n");
111 			}
112 			free(d->Msg.Buffer);
113 			d->Msg.Buffer = NULL;
114 			d->Msg.Length = 0;
115 			d->MsgRXState = RX_Sync;
116 			return ERR_NONE;
117 		}
118 		s->Phone.Data.RequestMsg = &d->Msg;
119 		s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s);
120 		free(d->Msg.Buffer);
121 		d->Msg.Buffer = NULL;
122 		d->Msg.Length = 0;
123 		d->MsgRXState = RX_Sync;
124 		return ERR_NONE;
125 	}
126 	return ERR_NONE;
127 }
128 
GNAPBUS_Initialise(GSM_StateMachine * s)129 static GSM_Error GNAPBUS_Initialise(GSM_StateMachine *s)
130 {
131 	GSM_Protocol_GNAPBUSData *d = &s->Protocol.Data.GNAPBUS;
132 
133 	d->Msg.BufferUsed	= 0;
134 	d->Msg.Buffer 		= NULL;
135 	d->Msg.Length		= 0;
136 
137 	d->MsgRXState 		= RX_Sync;
138 
139 	return ERR_NONE;
140 }
141 
GNAPBUS_Terminate(GSM_StateMachine * s)142 static GSM_Error GNAPBUS_Terminate(GSM_StateMachine *s)
143 {
144 	free(s->Protocol.Data.GNAPBUS.Msg.Buffer);
145 	s->Protocol.Data.GNAPBUS.Msg.Buffer=NULL;
146 	return ERR_NONE;
147 }
148 
149 GSM_Protocol_Functions GNAPBUSProtocol = {
150 	GNAPBUS_WriteMessage,
151 	GNAPBUS_StateMachine,
152 	GNAPBUS_Initialise,
153 	GNAPBUS_Terminate
154 };
155 
156 #endif
157 
158 /* How should editor hadle tabs in this file? Add editor commands here.
159  * vim: noexpandtab sw=8 ts=8 sts=8:
160  */
161