1 /*!
2 * \file sccp_protocol.c
3 * \brief SCCP Protocol implementation.
4 * This file does the protocol implementation only. It should not be used as a controller.
5 * \author Marcello Ceschia <marcello.ceschia [at] users.sourceforge.net>
6 * \note This program is free software and may be modified and distributed under the terms of the GNU Public License.
7 * See the LICENSE file at the top of the source tree.
8 *
9 */
10
11 #include "config.h"
12 #include "common.h"
13 #include "sccp_channel.h"
14 #include "sccp_device.h"
15 #include "sccp_enum.h"
16 #include "sccp_line.h"
17 #include "sccp_protocol.h"
18 #include "sccp_linedevice.h"
19 #include "sccp_session.h"
20 #include "sccp_utils.h"
21 #include <asterisk/unaligned.h>
22 SCCP_FILE_VERSION(__FILE__, "");
23
24 /*!
25 * \brief Build an SCCP Message Packet
26 * \param[in] t SCCP Message Text
27 * \param[out] pkt_len Packet Length
28 * \return SCCP Message
29 */
sccp_build_packet(sccp_mid_t t,size_t pkt_len)30 messagePtr __attribute__((malloc)) sccp_build_packet(sccp_mid_t t, size_t pkt_len)
31 {
32 int padding = ((pkt_len + 8) % 4);
33 padding = (padding > 0) ? 4 - padding : 0;
34
35 sccp_msg_t * msg = (sccp_msg_t *)sccp_calloc(1, pkt_len + SCCP_PACKET_HEADER + padding);
36
37 if(!msg) {
38 pbx_log(LOG_WARNING, "SCCP: Packet memory allocation error\n");
39 return NULL;
40 }
41 msg->header.length = htolel(pkt_len + 4 + padding);
42 msg->header.lel_messageId = htolel(t);
43
44 // sccp_log(DEBUGCAT_DEVICE)("SCCP: (sccp_build_packet) created packet type:0x%x, msg_size=%lu, hdr_len=%lu\n", t, pkt_len + SCCP_PACKET_HEADER + padding, pkt_len + 4 + padding)
45 return msg;
46 }
47
48 /* CallInfo Message */
49
50 /* =================================================================================================================== Send Messages */
sccp_protocol_sendCallInfoV3(const sccp_callinfo_t * const ci,const uint32_t callid,const skinny_calltype_t calltype,const uint8_t lineInstance,const uint8_t callInstance,const skinny_callsecuritystate_t callsecurityState,constDevicePtr device)51 static void sccp_protocol_sendCallInfoV3 (const sccp_callinfo_t * const ci, const uint32_t callid, const skinny_calltype_t calltype, const uint8_t lineInstance, const uint8_t callInstance, const skinny_callsecuritystate_t callsecurityState, constDevicePtr device)
52 {
53 pbx_assert(device != NULL);
54 sccp_msg_t * msg = NULL;
55
56 REQ(msg, CallInfoMessage);
57
58 int originalCdpnRedirectReason = 0;
59 int lastRedirectingReason = 0;
60 sccp_callerid_presentation_t presentation = CALLERID_PRESENTATION_ALLOWED;
61
62 iCallInfo.Getter(ci,
63 SCCP_CALLINFO_CALLEDPARTY_NAME, &msg->data.CallInfoMessage.calledPartyName,
64 SCCP_CALLINFO_CALLEDPARTY_NUMBER, &msg->data.CallInfoMessage.calledParty,
65 SCCP_CALLINFO_CALLEDPARTY_VOICEMAIL, &msg->data.CallInfoMessage.cdpnVoiceMailbox,
66 SCCP_CALLINFO_CALLINGPARTY_NAME, &msg->data.CallInfoMessage.callingPartyName,
67 SCCP_CALLINFO_CALLINGPARTY_NUMBER, &msg->data.CallInfoMessage.callingParty,
68 SCCP_CALLINFO_CALLINGPARTY_VOICEMAIL, &msg->data.CallInfoMessage.cgpnVoiceMailbox,
69 SCCP_CALLINFO_ORIG_CALLEDPARTY_NAME, &msg->data.CallInfoMessage.originalCalledPartyName,
70 SCCP_CALLINFO_ORIG_CALLEDPARTY_NUMBER, &msg->data.CallInfoMessage.originalCalledParty,
71 SCCP_CALLINFO_ORIG_CALLEDPARTY_VOICEMAIL, &msg->data.CallInfoMessage.originalCdpnVoiceMailbox,
72 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &msg->data.CallInfoMessage.lastRedirectingPartyName,
73 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, &msg->data.CallInfoMessage.lastRedirectingParty,
74 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_VOICEMAIL, &msg->data.CallInfoMessage.lastRedirectingVoiceMailbox,
75 SCCP_CALLINFO_ORIG_CALLEDPARTY_REDIRECT_REASON, &originalCdpnRedirectReason,
76 SCCP_CALLINFO_LAST_REDIRECT_REASON, &lastRedirectingReason,
77 SCCP_CALLINFO_PRESENTATION, &presentation,
78 SCCP_CALLINFO_KEY_SENTINEL);
79
80 // 7920's exception. They don't seem to reverse the interpretation of the presentation flag
81 if (device->skinny_type == SKINNY_DEVICETYPE_CISCO7920) {
82 msg->data.CallInfoMessage.partyPIRestrictionBits = presentation ? 0x0 : 0xf;
83 } else {
84 msg->data.CallInfoMessage.partyPIRestrictionBits = presentation ? 0xf : 0x0;
85 }
86 msg->data.CallInfoMessage.lel_lineInstance = htolel(lineInstance);
87 msg->data.CallInfoMessage.lel_callReference = htolel(callid);
88 msg->data.CallInfoMessage.lel_callType = htolel(calltype);
89 msg->data.CallInfoMessage.lel_callInstance = htolel(callInstance);
90 msg->data.CallInfoMessage.lel_callSecurityStatus = htolel(callsecurityState);
91 msg->data.CallInfoMessage.lel_originalCdpnRedirectReason = htolel(originalCdpnRedirectReason);
92 msg->data.CallInfoMessage.lel_lastRedirectingReason = htolel(lastRedirectingReason);
93
94 //sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: Send callinfo(V3) for %s channel %d/%d on line instance %d\n", (device) ? device->id : "(null)", skinny_calltype2str(calltype), callid, callInstance, lineInstance);
95 //if ((GLOB(debug) & (DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) != 0) {
96 // iCallInfo.Print2log(ci, "SCCP: (sendCallInfoV3)");
97 //}
98 sccp_dev_send(device, msg);
99 }
100
sccp_protocol_sendCallInfoV7(const sccp_callinfo_t * const ci,const uint32_t callid,const skinny_calltype_t calltype,const uint8_t lineInstance,const uint8_t callInstance,const skinny_callsecuritystate_t callsecurityState,constDevicePtr device)101 static void sccp_protocol_sendCallInfoV7 (const sccp_callinfo_t * const ci, const uint32_t callid, const skinny_calltype_t calltype, const uint8_t lineInstance, const uint8_t callInstance, const skinny_callsecuritystate_t callsecurityState, constDevicePtr device)
102 {
103 pbx_assert(device != NULL);
104 sccp_msg_t *msg = NULL;
105
106 unsigned int dataSize = 12;
107 char data[dataSize][StationMaxNameSize];
108 int data_len[dataSize];
109 unsigned int i = 0;
110 int dummy_len = 0;
111
112 memset(data, 0, dataSize * StationMaxNameSize);
113
114 int originalCdpnRedirectReason = 0;
115 int lastRedirectingReason = 0;
116 sccp_callerid_presentation_t presentation = CALLERID_PRESENTATION_ALLOWED;
117 iCallInfo.Getter(ci,
118 SCCP_CALLINFO_CALLINGPARTY_NUMBER, &data[0],
119 SCCP_CALLINFO_CALLEDPARTY_NUMBER, &data[1],
120 SCCP_CALLINFO_ORIG_CALLEDPARTY_NUMBER, &data[2],
121 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, &data[3],
122 SCCP_CALLINFO_CALLINGPARTY_VOICEMAIL, &data[4],
123 SCCP_CALLINFO_CALLEDPARTY_VOICEMAIL, &data[5],
124 SCCP_CALLINFO_ORIG_CALLEDPARTY_VOICEMAIL, &data[6],
125 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_VOICEMAIL, &data[7],
126 SCCP_CALLINFO_CALLINGPARTY_NAME, &data[8],
127 SCCP_CALLINFO_CALLEDPARTY_NAME, &data[9],
128 SCCP_CALLINFO_ORIG_CALLEDPARTY_NAME, &data[10],
129 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &data[11],
130 SCCP_CALLINFO_ORIG_CALLEDPARTY_REDIRECT_REASON, &originalCdpnRedirectReason,
131 SCCP_CALLINFO_LAST_REDIRECT_REASON, &lastRedirectingReason,
132 SCCP_CALLINFO_PRESENTATION, &presentation,
133 SCCP_CALLINFO_KEY_SENTINEL);
134
135
136 for (i = 0; i < dataSize; i++) {
137 data_len[i] = strlen(data[i]);
138 dummy_len += data_len[i];
139 }
140
141 int hdr_len = sizeof(msg->data.CallInfoDynamicMessage) + (dataSize - 3);
142 msg = sccp_build_packet(CallInfoDynamicMessage, hdr_len + dummy_len);
143
144 msg->data.CallInfoDynamicMessage.lel_lineInstance = htolel(lineInstance);
145 msg->data.CallInfoDynamicMessage.lel_callReference = htolel(callid);
146 msg->data.CallInfoDynamicMessage.lel_callType = htolel(calltype);
147 msg->data.CallInfoDynamicMessage.partyPIRestrictionBits = presentation ? 0x0 : 0xf;
148 //! note callSecurityStatus:
149 // when indicating ringout we should set SKINNY_CALLSECURITYSTATE_UNKNOWN
150 // when indicating connected we should set SKINNY_CALLSECURITYSTATE_NOTAUTHENTICATED
151 msg->data.CallInfoDynamicMessage.lel_callSecurityStatus = htolel(callsecurityState);
152 msg->data.CallInfoDynamicMessage.lel_callInstance = htolel(callInstance);
153 msg->data.CallInfoDynamicMessage.lel_originalCdpnRedirectReason = htolel(originalCdpnRedirectReason);
154 msg->data.CallInfoDynamicMessage.lel_lastRedirectingReason = htolel(lastRedirectingReason);
155
156 if (dummy_len) {
157 int bufferSize = dummy_len + dataSize;
158 char buffer[bufferSize];
159 int pos = 0;
160
161 memset(&buffer[0], 0, bufferSize);
162 for (i = 0; i < dataSize; i++) {
163 if (data_len[i]) {
164 memcpy(&buffer[pos], data[i], data_len[i]);
165 pos += data_len[i] + 1;
166 } else {
167 pos += 1;
168 }
169 }
170 memcpy(&msg->data.CallInfoDynamicMessage.dummy, &buffer[0], bufferSize);
171 }
172
173 //sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: Send callinfo(V7) for %s channel %d/%d on line instance %d\n", (device) ? device->id : "(null)", skinny_calltype2str(calltype), callid, callInstance, lineInstance);
174 //if ((GLOB(debug) & (DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) != 0) {
175 // iCallInfo.Print2log(ci, "SCCP: (sendCallInfoV7)");
176 // sccp_dump_msg(msg);
177 //}
178 sccp_dev_send(device, msg);
179 }
180
sccp_protocol_sendCallInfoV16(const sccp_callinfo_t * const ci,const uint32_t callid,const skinny_calltype_t calltype,const uint8_t lineInstance,const uint8_t callInstance,const skinny_callsecuritystate_t callsecurityState,constDevicePtr device)181 static void sccp_protocol_sendCallInfoV16 (const sccp_callinfo_t * const ci, const uint32_t callid, const skinny_calltype_t calltype, const uint8_t lineInstance, const uint8_t callInstance, const skinny_callsecuritystate_t callsecurityState, constDevicePtr device)
182 {
183 pbx_assert(device != NULL);
184 sccp_msg_t *msg = NULL;
185
186 unsigned int dataSize = 15;
187 char data[dataSize][StationMaxNameSize];
188 memset(data, 0, dataSize * StationMaxNameSize);
189
190 int originalCdpnRedirectReason = 0;
191 int lastRedirectingReason = 0;
192 sccp_callerid_presentation_t presentation = CALLERID_PRESENTATION_ALLOWED;
193 iCallInfo.Getter(ci,
194 SCCP_CALLINFO_CALLINGPARTY_NUMBER, &data[0],
195 SCCP_CALLINFO_ORIG_CALLINGPARTY_NUMBER, &data[1],
196 SCCP_CALLINFO_CALLEDPARTY_NUMBER, &data[2],
197 SCCP_CALLINFO_ORIG_CALLEDPARTY_NUMBER, &data[3],
198 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NUMBER, &data[4],
199 SCCP_CALLINFO_CALLINGPARTY_VOICEMAIL, &data[5],
200 SCCP_CALLINFO_CALLEDPARTY_VOICEMAIL, &data[6],
201 SCCP_CALLINFO_ORIG_CALLEDPARTY_VOICEMAIL, &data[7],
202 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_VOICEMAIL, &data[8],
203 SCCP_CALLINFO_CALLINGPARTY_NAME, &data[9],
204 SCCP_CALLINFO_CALLEDPARTY_NAME, &data[10],
205 SCCP_CALLINFO_ORIG_CALLEDPARTY_NAME, &data[11],
206 SCCP_CALLINFO_LAST_REDIRECTINGPARTY_NAME, &data[12],
207 SCCP_CALLINFO_HUNT_PILOT_NUMBER, &data[13],
208 SCCP_CALLINFO_HUNT_PILOT_NAME, &data[14],
209 SCCP_CALLINFO_ORIG_CALLEDPARTY_REDIRECT_REASON, &originalCdpnRedirectReason,
210 SCCP_CALLINFO_LAST_REDIRECT_REASON, &lastRedirectingReason,
211 SCCP_CALLINFO_PRESENTATION, &presentation,
212 SCCP_CALLINFO_KEY_SENTINEL);
213
214 unsigned int field = 0;
215 int data_len = 0;
216 int dummy_len = 0;
217 uint8_t *dummy = (uint8_t *)sccp_calloc(sizeof(uint8_t), dataSize * StationMaxNameSize);
218 if (!dummy) {
219 return;
220 }
221 for (field = 0; field < dataSize; field++) {
222 data_len = strlen(data[field]) + 1; //add NULL terminator
223 memcpy(dummy + dummy_len, data[field], data_len);
224 dummy_len += data_len;
225 }
226 int hdr_len = sizeof(msg->data.CallInfoDynamicMessage) - 4;
227 msg = sccp_build_packet(CallInfoDynamicMessage, hdr_len + dummy_len);
228 msg->data.CallInfoDynamicMessage.lel_lineInstance = htolel(lineInstance);
229 msg->data.CallInfoDynamicMessage.lel_callReference = htolel(callid);
230 msg->data.CallInfoDynamicMessage.lel_callType = htolel(calltype);
231 msg->data.CallInfoDynamicMessage.partyPIRestrictionBits = presentation ? 0x0 : 0xf;
232 msg->data.CallInfoDynamicMessage.lel_callSecurityStatus = htolel(callsecurityState);
233 msg->data.CallInfoDynamicMessage.lel_callInstance = htolel(callInstance);
234 msg->data.CallInfoDynamicMessage.lel_originalCdpnRedirectReason = htolel(originalCdpnRedirectReason);
235 msg->data.CallInfoDynamicMessage.lel_lastRedirectingReason = htolel(lastRedirectingReason);
236 memcpy(&msg->data.CallInfoDynamicMessage.dummy, dummy, dummy_len);
237 sccp_free(dummy);
238
239 //sccp_log((DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) (VERBOSE_PREFIX_3 "%s: Send callinfo(V20) for %s channel %d/%d on line instance %d\n", (device) ? device->id : "(null)", skinny_calltype2str(calltype), callid, callInstance, lineInstance);
240 //if ((GLOB(debug) & (DEBUGCAT_CHANNEL | DEBUGCAT_LINE | DEBUGCAT_INDICATE)) != 0) {
241 // iCallInfo.Print2log(ci, "SCCP: (sendCallInfoV16)");
242 // sccp_dump_msg(msg);
243 //}
244 sccp_dev_send(device, msg);
245 }
246
247 /* done - CallInfoMessage */
248
249
250 /* DialedNumber Message */
251
252 /*!
253 * \brief Send DialedNumber Message (V3)
254 */
sccp_protocol_sendDialedNumberV3(constDevicePtr device,const uint8_t lineInstance,const uint32_t callid,const char dialedNumber[SCCP_MAX_EXTENSION])255 static void sccp_protocol_sendDialedNumberV3(constDevicePtr device, const uint8_t lineInstance, const uint32_t callid, const char dialedNumber[SCCP_MAX_EXTENSION])
256 {
257 sccp_msg_t *msg = NULL;
258
259 REQ(msg, DialedNumberMessage);
260
261 sccp_copy_string(msg->data.DialedNumberMessage.v3.calledParty, dialedNumber, sizeof(msg->data.DialedNumberMessage.v3.calledParty));
262
263 msg->data.DialedNumberMessage.v3.lel_lineInstance = htolel(lineInstance);
264 msg->data.DialedNumberMessage.v3.lel_callReference = htolel(callid);
265
266 sccp_dev_send(device, msg);
267 sccp_log(DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "%s: Send the dialed number:%s, callid:%d, lineInstance:%d\n", device->id, dialedNumber, callid, lineInstance);
268 }
269
270 /*!
271 * \brief Send DialedNumber Message (V18)
272 *
273 */
sccp_protocol_sendDialedNumberV18(constDevicePtr device,const uint8_t lineInstance,const uint32_t callid,const char dialedNumber[SCCP_MAX_EXTENSION])274 static void sccp_protocol_sendDialedNumberV18(constDevicePtr device, const uint8_t lineInstance, const uint32_t callid, const char dialedNumber[SCCP_MAX_EXTENSION])
275 {
276 sccp_msg_t *msg = NULL;
277
278 REQ(msg, DialedNumberMessage);
279
280 sccp_copy_string(msg->data.DialedNumberMessage.v18.calledParty, dialedNumber, sizeof(msg->data.DialedNumberMessage.v18.calledParty));
281 msg->data.DialedNumberMessage.v18.lel_lineInstance = htolel(lineInstance);
282 msg->data.DialedNumberMessage.v18.lel_callReference = htolel(callid);
283
284 sccp_dev_send(device, msg);
285 sccp_log(DEBUGCAT_CHANNEL) (VERBOSE_PREFIX_3 "%s: Send the dialed number:%s, callid:%d, lineInstance:%d\n", device->id, dialedNumber, callid, lineInstance);
286 }
287
288 /* done - DialedNumber Message */
289
290 /* Display Prompt Message */
291
292 /*!
293 * \brief Send Display Prompt Message (Static)
294 */
sccp_protocol_sendStaticDisplayprompt(constDevicePtr device,uint8_t lineInstance,uint32_t callid,uint8_t timeout,const char * message)295 static void sccp_protocol_sendStaticDisplayprompt(constDevicePtr device, uint8_t lineInstance, uint32_t callid, uint8_t timeout, const char *message)
296 {
297 sccp_msg_t *msg = NULL;
298
299 REQ(msg, DisplayPromptStatusMessage);
300 msg->data.DisplayPromptStatusMessage.lel_messageTimeout = htolel(timeout);
301 msg->data.DisplayPromptStatusMessage.lel_callReference = htolel(callid);
302 msg->data.DisplayPromptStatusMessage.lel_lineInstance = htolel(lineInstance);
303 sccp_copy_string(msg->data.DisplayPromptStatusMessage.promptMessage, message, sizeof(msg->data.DisplayPromptStatusMessage.promptMessage));
304
305 sccp_dev_send(device, msg);
306 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display prompt on line %d, callid %d, timeout %d\n", device->id, lineInstance, callid, timeout);
307 }
308
309 /*!
310 * \brief Send Display Prompt Message (Dynamic)
311 */
sccp_protocol_sendDynamicDisplayprompt(constDevicePtr device,uint8_t lineInstance,uint32_t callid,uint8_t timeout,const char * message)312 static void sccp_protocol_sendDynamicDisplayprompt(constDevicePtr device, uint8_t lineInstance, uint32_t callid, uint8_t timeout, const char *message)
313 {
314 sccp_msg_t *msg = NULL;
315
316 int msg_len = strlen(message);
317 int hdr_len = sizeof(msg->data.DisplayDynamicPromptStatusMessage) - 3;
318 msg = sccp_build_packet(DisplayDynamicPromptStatusMessage, hdr_len + msg_len);
319 msg->data.DisplayDynamicPromptStatusMessage.lel_messageTimeout = htolel(timeout);
320 msg->data.DisplayDynamicPromptStatusMessage.lel_callReference = htolel(callid);
321 msg->data.DisplayDynamicPromptStatusMessage.lel_lineInstance = htolel(lineInstance);
322 memcpy(&msg->data.DisplayDynamicPromptStatusMessage.dummy, message, msg_len);
323
324 sccp_dev_send(device, msg);
325 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display prompt on line %d, callid %d, timeout %d\n", device->id, lineInstance, callid, timeout);
326 }
327
328 /* done - display prompt */
329
330 /* Display Notify Message */
331
332 /*!
333 * \brief Send Display Notify Message (Static)
334 */
sccp_protocol_sendStaticDisplayNotify(constDevicePtr device,uint8_t timeout,const char * message)335 static void sccp_protocol_sendStaticDisplayNotify(constDevicePtr device, uint8_t timeout, const char *message)
336 {
337 sccp_msg_t *msg = NULL;
338
339 REQ(msg, DisplayNotifyMessage);
340 msg->data.DisplayNotifyMessage.lel_displayTimeout = htolel(timeout);
341 sccp_copy_string(msg->data.DisplayNotifyMessage.displayMessage, message, sizeof(msg->data.DisplayNotifyMessage.displayMessage));
342
343 sccp_dev_send(device, msg);
344 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display notify timeout %d\n", device->id, timeout);
345 }
346
347 /*!
348 * \brief Send Display Notify Message (Dynamic)
349 */
sccp_protocol_sendDynamicDisplayNotify(constDevicePtr device,uint8_t timeout,const char * message)350 static void sccp_protocol_sendDynamicDisplayNotify(constDevicePtr device, uint8_t timeout, const char *message)
351 {
352 sccp_msg_t *msg = NULL;
353
354 int msg_len = strlen(message);
355
356 int hdr_len = sizeof(msg->data.DisplayDynamicNotifyMessage) - 3;
357 msg = sccp_build_packet(DisplayDynamicNotifyMessage, hdr_len + msg_len);
358 msg->data.DisplayDynamicNotifyMessage.lel_displayTimeout = htolel(timeout);
359 memcpy(&msg->data.DisplayDynamicNotifyMessage.dummy, message, msg_len);
360
361 sccp_dev_send(device, msg);
362 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display notify timeout %d\n", device->id, timeout);
363 }
364
365 /* done - display notify */
366
367 /* Display Priority Notify Message */
368
369 /*!
370 * \brief Send Priority Display Notify Message (Static)
371 */
sccp_protocol_sendStaticDisplayPriNotify(constDevicePtr device,uint8_t priority,uint8_t timeout,const char * message)372 static void sccp_protocol_sendStaticDisplayPriNotify(constDevicePtr device, uint8_t priority, uint8_t timeout, const char *message)
373 {
374 sccp_msg_t *msg = NULL;
375
376 REQ(msg, DisplayPriNotifyMessage);
377 msg->data.DisplayPriNotifyMessage.lel_displayTimeout = htolel(timeout);
378 msg->data.DisplayPriNotifyMessage.lel_priority = htolel(priority);
379 sccp_copy_string(msg->data.DisplayPriNotifyMessage.displayMessage, message, sizeof(msg->data.DisplayPriNotifyMessage.displayMessage));
380
381 sccp_dev_send(device, msg);
382 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display notify timeout %d\n", device->id, timeout);
383 }
384
385 /*!
386 * \brief Send Priority Display Notify Message (Dynamic)
387 */
sccp_protocol_sendDynamicDisplayPriNotify(constDevicePtr device,uint8_t priority,uint8_t timeout,const char * message)388 static void sccp_protocol_sendDynamicDisplayPriNotify(constDevicePtr device, uint8_t priority, uint8_t timeout, const char *message)
389 {
390 sccp_msg_t *msg = NULL;
391
392 int msg_len = strlen(message);
393 int hdr_len = sizeof(msg->data.DisplayDynamicPriNotifyMessage) - 3;
394 msg = sccp_build_packet(DisplayDynamicPriNotifyMessage, hdr_len + msg_len);
395 msg->data.DisplayDynamicPriNotifyMessage.lel_displayTimeout = htolel(timeout);
396 msg->data.DisplayDynamicPriNotifyMessage.lel_priority = htolel(priority);
397 memcpy(&msg->data.DisplayDynamicPriNotifyMessage.dummy, message, msg_len);
398
399 sccp_dev_send(device, msg);
400 sccp_log((DEBUGCAT_DEVICE | DEBUGCAT_LINE)) (VERBOSE_PREFIX_3 "%s: Display notify timeout %d\n", device->id, timeout);
401 }
402
403 /* done - display notify */
404
405 /* callForwardStatus Message */
406
407 /*!
408 * \brief Send Call Forward Status Message
409 * \todo need more information about lel_activeForward and lel_forwardAllActive values.
410 */
sccp_protocol_sendCallForwardStatus(constDevicePtr device,const sccp_linedevice_t * ld)411 static void sccp_protocol_sendCallForwardStatus(constDevicePtr device, const sccp_linedevice_t * ld)
412 {
413 sccp_msg_t *msg = NULL;
414
415 REQ(msg, ForwardStatMessage);
416 msg->data.ForwardStatMessage.v3.lel_activeForward = (ld->cfwd[SCCP_CFWD_ALL].enabled || ld->cfwd[SCCP_CFWD_BUSY].enabled || ld->cfwd[SCCP_CFWD_NOANSWER].enabled) ? htolel(1) : 0;
417 msg->data.ForwardStatMessage.v3.lel_lineNumber = htolel(ld->lineInstance);
418
419 if(ld->cfwd[SCCP_CFWD_ALL].enabled) {
420 msg->data.ForwardStatMessage.v3.lel_forwardAllActive = htolel(1);
421 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdallnumber, ld->cfwd[SCCP_CFWD_ALL].number, sizeof(msg->data.ForwardStatMessage.v3.cfwdallnumber));
422 } else if(ld->cfwd[SCCP_CFWD_BUSY].enabled) {
423 msg->data.ForwardStatMessage.v3.lel_forwardBusyActive = htolel(1);
424 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdbusynumber, ld->cfwd[SCCP_CFWD_BUSY].number, sizeof(msg->data.ForwardStatMessage.v3.cfwdbusynumber));
425 } else if(ld->cfwd[SCCP_CFWD_NOANSWER].enabled) {
426 msg->data.ForwardStatMessage.v3.lel_forwardNoAnswerActive = htolel(1);
427 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdnoanswernumber, ld->cfwd[SCCP_CFWD_NOANSWER].number, sizeof(msg->data.ForwardStatMessage.v3.cfwdnoanswernumber));
428 } else {
429 msg->data.ForwardStatMessage.v3.lel_forwardAllActive = htolel(0);
430 msg->data.ForwardStatMessage.v3.lel_forwardBusyActive = htolel(0);
431 msg->data.ForwardStatMessage.v3.lel_forwardNoAnswerActive = htolel(0);
432 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdallnumber, "", sizeof(msg->data.ForwardStatMessage.v3.cfwdbusynumber));
433 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdbusynumber, "", sizeof(msg->data.ForwardStatMessage.v3.cfwdbusynumber));
434 sccp_copy_string(msg->data.ForwardStatMessage.v3.cfwdnoanswernumber, "", sizeof(msg->data.ForwardStatMessage.v3.cfwdnoanswernumber));
435 }
436 sccp_dev_send(device, msg);
437 }
438
439 /*!
440 * \brief Send Call Forward Status Message (V19)
441 * \todo need more information about lel_activeForward and lel_forwardAllActive values.
442 */
sccp_protocol_sendCallForwardStatusV18(constDevicePtr device,const sccp_linedevice_t * ld)443 static void sccp_protocol_sendCallForwardStatusV18(constDevicePtr device, const sccp_linedevice_t * ld)
444 {
445 sccp_msg_t *msg = NULL;
446
447 REQ(msg, ForwardStatMessage);
448 // activeForward / lel_forwardAllActive = used 4 before... tcpdump shows 2(enbloc ?) or 8(single keypad ?)
449 // msg->data.ForwardStatMessage.v18.lel_activeForward = (ld->cfwdAll.enabled || ld->cfwdBusy.enabled) ? htolel(2) : 0; // should this be 2 instead ?
450 msg->data.ForwardStatMessage.v18.lel_lineNumber = htolel(ld->lineInstance);
451 if(ld->cfwd[SCCP_CFWD_ALL].enabled) {
452 msg->data.ForwardStatMessage.v18.lel_activeForward = 2;
453 msg->data.ForwardStatMessage.v18.lel_forwardAllActive = htolel(2); // needs more information about the possible values and their meaning // 2 ?
454 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdallnumber, ld->cfwd[SCCP_CFWD_ALL].number, sizeof(msg->data.ForwardStatMessage.v18.cfwdallnumber));
455 } else if(ld->cfwd[SCCP_CFWD_BUSY].enabled) {
456 msg->data.ForwardStatMessage.v18.lel_activeForward = 2;
457 msg->data.ForwardStatMessage.v18.lel_forwardBusyActive = htolel(2);
458 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdbusynumber, ld->cfwd[SCCP_CFWD_BUSY].number, sizeof(msg->data.ForwardStatMessage.v18.cfwdbusynumber));
459 } else if(ld->cfwd[SCCP_CFWD_NOANSWER].enabled) {
460 msg->data.ForwardStatMessage.v18.lel_activeForward = 2;
461 msg->data.ForwardStatMessage.v18.lel_forwardNoAnswerActive = htolel(2);
462 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdnoanswernumber, ld->cfwd[SCCP_CFWD_NOANSWER].number, sizeof(msg->data.ForwardStatMessage.v18.cfwdnoanswernumber));
463 } else {
464 msg->data.ForwardStatMessage.v18.lel_activeForward = 0;
465 msg->data.ForwardStatMessage.v18.lel_forwardAllActive = htolel(0);
466 msg->data.ForwardStatMessage.v18.lel_forwardBusyActive = htolel(0);
467 msg->data.ForwardStatMessage.v18.lel_forwardNoAnswerActive = htolel(0);
468 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdallnumber, "", sizeof(msg->data.ForwardStatMessage.v18.cfwdbusynumber));
469 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdbusynumber, "", sizeof(msg->data.ForwardStatMessage.v18.cfwdbusynumber));
470 sccp_copy_string(msg->data.ForwardStatMessage.v18.cfwdnoanswernumber, "", sizeof(msg->data.ForwardStatMessage.v18.cfwdnoanswernumber));
471 }
472
473 //msg->data.ForwardStatMessage.v18.lel_unknown = 0x000000FF;
474 sccp_dev_send(device, msg);
475 }
476
477 /* done - send callForwardStatus */
478
479 /* registerAck Message */
480
481 /*!
482 * \brief Send Register Acknowledgement Message (V3)
483 */
sccp_protocol_sendRegisterAckV3(constDevicePtr device,uint8_t keepAliveInterval,uint8_t secondaryKeepAlive,char * dateformat)484 static void sccp_protocol_sendRegisterAckV3(constDevicePtr device, uint8_t keepAliveInterval, uint8_t secondaryKeepAlive, char *dateformat)
485 {
486 sccp_msg_t *msg = NULL;
487
488 REQ(msg, RegisterAckMessage);
489
490 /* just for documentation */
491 msg->data.RegisterAckMessage.protocolFeatures.protocolVersion = device->protocol->version;
492 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[0] = 0x00;
493 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[1] = 0x00;
494 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[2] = 0x00;
495
496 msg->data.RegisterAckMessage.lel_keepAliveInterval = htolel(keepAliveInterval);
497 msg->data.RegisterAckMessage.lel_secondaryKeepAliveInterval = htolel(secondaryKeepAlive);
498
499 if (!sccp_strlen_zero(dateformat)) {
500 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, dateformat, sizeof(msg->data.RegisterAckMessage.dateTemplate));
501 } else {
502 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, "M/D/Y", sizeof(msg->data.RegisterAckMessage.dateTemplate));
503 }
504 sccp_dev_send(device, msg);
505 }
506
507 /*!
508 * \brief Send Register Acknowledgement Message (V4)
509 */
sccp_protocol_sendRegisterAckV4(constDevicePtr device,uint8_t keepAliveInterval,uint8_t secondaryKeepAlive,char * dateformat)510 static void sccp_protocol_sendRegisterAckV4(constDevicePtr device, uint8_t keepAliveInterval, uint8_t secondaryKeepAlive, char *dateformat)
511 {
512 sccp_msg_t *msg = NULL;
513
514 REQ(msg, RegisterAckMessage);
515
516 msg->data.RegisterAckMessage.protocolFeatures.protocolVersion = device->protocol->version;
517 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[0] = 0x20;
518 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[1] = 0xF1;
519 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[2] = 0xFE;
520
521 msg->data.RegisterAckMessage.lel_keepAliveInterval = htolel(keepAliveInterval);
522 msg->data.RegisterAckMessage.lel_secondaryKeepAliveInterval = htolel(secondaryKeepAlive);
523
524 if (!sccp_strlen_zero(dateformat)) {
525 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, dateformat, sizeof(msg->data.RegisterAckMessage.dateTemplate));
526 } else {
527 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, "M/D/Y", sizeof(msg->data.RegisterAckMessage.dateTemplate));
528 }
529 sccp_dev_send(device, msg);
530 }
531
532 /*!
533 * \brief Send Register Acknowledgement Message (V11)
534 */
sccp_protocol_sendRegisterAckV11(constDevicePtr device,uint8_t keepAliveInterval,uint8_t secondaryKeepAlive,char * dateformat)535 static void sccp_protocol_sendRegisterAckV11(constDevicePtr device, uint8_t keepAliveInterval, uint8_t secondaryKeepAlive, char *dateformat)
536 {
537 sccp_msg_t *msg = NULL;
538
539 REQ(msg, RegisterAckMessage);
540
541 msg->data.RegisterAckMessage.protocolFeatures.protocolVersion = device->protocol->version;
542 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[0] = 0x20;
543 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[1] = 0xF1;
544 msg->data.RegisterAckMessage.protocolFeatures.phoneFeatures[2] = 0xFF;
545
546 msg->data.RegisterAckMessage.lel_keepAliveInterval = htolel(keepAliveInterval);
547 msg->data.RegisterAckMessage.lel_secondaryKeepAliveInterval = htolel(secondaryKeepAlive);
548
549 if (!sccp_strlen_zero(dateformat)) {
550 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, dateformat, sizeof(msg->data.RegisterAckMessage.dateTemplate));
551 } else {
552 sccp_copy_string(msg->data.RegisterAckMessage.dateTemplate, "M/D/Y", sizeof(msg->data.RegisterAckMessage.dateTemplate));
553 }
554 sccp_dev_send(device, msg);
555 }
556 /* done - registerACK */
557
558 /*!
559 * \brief Send Open Receive Channel (V3)
560 */
sccp_protocol_sendOpenReceiveChannelV3(constDevicePtr device,constChannelPtr channel)561 static void sccp_protocol_sendOpenReceiveChannelV3(constDevicePtr device, constChannelPtr channel)
562 {
563 int packetSize = 20; /*! \todo calculate packetSize */
564 sccp_msg_t *msg = sccp_build_packet(OpenReceiveChannel, sizeof(msg->data.OpenReceiveChannel.v3));
565
566 msg->data.OpenReceiveChannel.v3.lel_conferenceId = htolel(channel->callid);
567 msg->data.OpenReceiveChannel.v3.lel_passThruPartyId = htolel(channel->passthrupartyid);
568 msg->data.OpenReceiveChannel.v3.lel_millisecondPacketSize = htolel(packetSize);
569 msg->data.OpenReceiveChannel.v3.lel_codecType = htolel(channel->rtp.audio.reception.format);
570 msg->data.OpenReceiveChannel.v3.lel_vadValue = htolel(channel->line->echocancel);
571 msg->data.OpenReceiveChannel.v3.lel_callReference = htolel(channel->callid);
572 //msg->data.OpenReceiveChannel.v3.lel_remotePortNumber = htolel(4000);
573 if (SCCP_DTMFMODE_SKINNY == channel->dtmfmode) {
574 msg->data.OpenReceiveChannel.v3.lel_RFC2833Type = htolel(0);
575 } else {
576 msg->data.OpenReceiveChannel.v3.lel_RFC2833Type = htolel(101);
577 }
578 msg->data.OpenReceiveChannel.v3.lel_dtmfType = htolel(10);;
579
580 /* Source Ip Address */
581 struct sockaddr_storage sas;
582
583 memcpy(&sas, &channel->rtp.audio.phone_remote, sizeof(struct sockaddr_storage));
584 sccp_netsock_ipv4_mapped(&sas, &sas);
585
586 struct sockaddr_in *in = (struct sockaddr_in *) &sas;
587
588 memcpy(&msg->data.OpenReceiveChannel.v3.bel_remoteIpAddr, &in->sin_addr, 4);
589 msg->data.OpenReceiveChannel.v3.lel_remotePortNumber = htolel(sccp_netsock_getPort(&sas));
590
591 sccp_dev_send(device, msg);
592 }
593
594 /*!
595 * \brief Send Open Receive Channel (V17)
596 */
sccp_protocol_sendOpenReceiveChannelV17(constDevicePtr device,constChannelPtr channel)597 static void sccp_protocol_sendOpenReceiveChannelV17(constDevicePtr device, constChannelPtr channel)
598 {
599 int packetSize = 20; /*! \todo calculate packetSize */
600 sccp_msg_t *msg = sccp_build_packet(OpenReceiveChannel, sizeof(msg->data.OpenReceiveChannel.v17));
601
602 msg->data.OpenReceiveChannel.v17.lel_conferenceId = htolel(channel->callid);
603 msg->data.OpenReceiveChannel.v17.lel_passThruPartyId = htolel(channel->passthrupartyid);
604 msg->data.OpenReceiveChannel.v17.lel_millisecondPacketSize = htolel(packetSize);
605 msg->data.OpenReceiveChannel.v17.lel_codecType = htolel(channel->rtp.audio.reception.format);
606 msg->data.OpenReceiveChannel.v17.lel_vadValue = htolel(channel->line->echocancel);
607 msg->data.OpenReceiveChannel.v17.lel_callReference = htolel(channel->callid);
608 if (SCCP_DTMFMODE_SKINNY == channel->dtmfmode) {
609 msg->data.OpenReceiveChannel.v17.lel_RFC2833Type = htolel(0);
610 } else {
611 msg->data.OpenReceiveChannel.v17.lel_RFC2833Type = htolel(101);
612 }
613 msg->data.OpenReceiveChannel.v17.lel_dtmfType = htolel(10);;
614
615 /* Source Ip Address */
616 struct sockaddr_storage sas;
617
618 //memcpy(&sas, &device->session->sin, sizeof(struct sockaddr_storage));
619 memcpy(&sas, &channel->rtp.audio.phone_remote, sizeof(struct sockaddr_storage));
620 sccp_netsock_ipv4_mapped(&sas, &sas);
621
622 if (sas.ss_family == AF_INET6) {
623 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &sas;
624
625 memcpy(&msg->data.OpenReceiveChannel.v17.bel_remoteIpAddr, &in6->sin6_addr, 16);
626 msg->data.OpenReceiveChannel.v17.lel_ipv46 = htolel(1);
627 msg->data.OpenReceiveChannel.v17.lel_requestedIpAddrType = htolel(SKINNY_IPADDR_IPV6); //for ipv6 this value have to me > 0, lel_ipv46 doesn't matter
628 } else {
629 struct sockaddr_in *in = (struct sockaddr_in *) &sas;
630
631 memcpy(&msg->data.OpenReceiveChannel.v17.bel_remoteIpAddr, &in->sin_addr, 4);
632 }
633 msg->data.OpenReceiveChannel.v17.lel_remotePortNumber = htolel(sccp_netsock_getPort(&sas));
634 sccp_dev_send(device, msg);
635 }
636
637 /*!
638 * \brief Send Open Receive Channel (v22)
639 */
sccp_protocol_sendOpenReceiveChannelv22(constDevicePtr device,constChannelPtr channel)640 static void sccp_protocol_sendOpenReceiveChannelv22(constDevicePtr device, constChannelPtr channel)
641 {
642 int packetSize = 20; /*! \todo calculate packetSize */
643 sccp_msg_t *msg = sccp_build_packet(OpenReceiveChannel, sizeof(msg->data.OpenReceiveChannel.v22));
644
645 msg->data.OpenReceiveChannel.v22.lel_conferenceId = htolel(channel->callid);
646 msg->data.OpenReceiveChannel.v22.lel_passThruPartyId = htolel(channel->passthrupartyid);
647 msg->data.OpenReceiveChannel.v22.lel_millisecondPacketSize = htolel(packetSize);
648 msg->data.OpenReceiveChannel.v22.lel_codecType = htolel(channel->rtp.audio.reception.format);
649 msg->data.OpenReceiveChannel.v22.lel_vadValue = htolel(channel->line->echocancel);
650 msg->data.OpenReceiveChannel.v22.lel_callReference = htolel(channel->callid);
651 if (SCCP_DTMFMODE_SKINNY == channel->dtmfmode) {
652 msg->data.OpenReceiveChannel.v22.lel_RFC2833Type = htolel(0);
653 } else {
654 msg->data.OpenReceiveChannel.v22.lel_RFC2833Type = htolel(101);
655 }
656 msg->data.OpenReceiveChannel.v22.lel_dtmfType = htolel(10);;
657
658 /* Source Ip Address */
659 struct sockaddr_storage sas;
660
661 //memcpy(&sas, &device->session->sin, sizeof(struct sockaddr_storage));
662 memcpy(&sas, &channel->rtp.audio.phone_remote, sizeof(struct sockaddr_storage));
663 sccp_netsock_ipv4_mapped(&sas, &sas);
664
665 if (sas.ss_family == AF_INET6) {
666 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &sas;
667
668 memcpy(&msg->data.OpenReceiveChannel.v22.bel_remoteIpAddr, &in6->sin6_addr, 16);
669 msg->data.OpenReceiveChannel.v22.lel_ipv46 = htolel(1); //for ipv6 this value have to me > 0, lel_ipv46 doesn't matter
670 msg->data.OpenReceiveChannel.v22.lel_requestedIpAddrType = htolel(SKINNY_IPADDR_IPV6);
671 } else {
672 struct sockaddr_in *in = (struct sockaddr_in *) &sas;
673
674 memcpy(&msg->data.OpenReceiveChannel.v22.bel_remoteIpAddr, &in->sin_addr, 4);
675 }
676 msg->data.OpenReceiveChannel.v22.lel_remotePortNumber = htolel(sccp_netsock_getPort(&sas));
677 sccp_dev_send(device, msg);
678 }
679
680 /*!
681 * \brief Send Open MultiMediaChannel Message (V3)
682 */
sccp_protocol_sendOpenMultiMediaChannelV3(constDevicePtr device,constChannelPtr channel,skinny_codec_t skinnyFormat,int payloadType,uint8_t lineInstance,int bitRate)683 static void sccp_protocol_sendOpenMultiMediaChannelV3(constDevicePtr device, constChannelPtr channel, skinny_codec_t skinnyFormat, int payloadType, uint8_t lineInstance, int bitRate)
684 {
685 sccp_msg_t *msg = sccp_build_packet(OpenMultiMediaChannelMessage, sizeof(msg->data.OpenMultiMediaChannelMessage.v3));
686
687 msg->data.OpenMultiMediaChannelMessage.v3.lel_conferenceID = htolel(channel->callid);
688 msg->data.OpenMultiMediaChannelMessage.v3.lel_passThruPartyID = htolel(channel->passthrupartyid);
689 msg->data.OpenMultiMediaChannelMessage.v3.lel_codecType = htolel(skinnyFormat);
690 //msg->data.OpenMultiMediaChannelMessage.v3.lel_codecType = htolel(channel->rtp.video.reception.format);
691 msg->data.OpenMultiMediaChannelMessage.v3.lel_lineInstance = htolel(lineInstance);
692 msg->data.OpenMultiMediaChannelMessage.v3.lel_callReference = htolel(channel->callid);
693
694 msg->data.OpenMultiMediaChannelMessage.v3.payloadType.lel_payload_rfc_number = htolel(0);
695 msg->data.OpenMultiMediaChannelMessage.v3.payloadType.lel_payloadType = htolel(payloadType);
696
697 msg->data.OpenMultiMediaChannelMessage.v3.lel_isConferenceCreator = htolel(0);
698
699 skinny_OpenMultiMediaReceiveChannelUnion_t *capability = &(msg->data.OpenMultiMediaChannelMessage.v3.capability);
700 {
701 capability->vidParameters.lel_bitRate = htolel(bitRate);
702 capability->vidParameters.lel_pictureFormatCount = htolel(1);
703
704 capability->vidParameters.pictureFormat[0].format = htolel(4); // should be taken from UpdateCapabilitiesMessage
705 capability->vidParameters.pictureFormat[0].mpi = htolel(1); // should be taken from UpdateCapabilitiesMessage
706 capability->vidParameters.pictureFormat[1].format = htolel(2);
707 capability->vidParameters.pictureFormat[1].mpi = htolel(1);
708 capability->vidParameters.pictureFormat[2].format = htolel(1);
709 capability->vidParameters.pictureFormat[2].mpi = htolel(1);
710 capability->vidParameters.pictureFormat[3].format = htolel(0);
711 capability->vidParameters.pictureFormat[3].mpi = htolel(1);
712 //capability->vidParameters.pictureFormat[4].format = htolel(0);
713 //capability->vidParameters.pictureFormat[4].mpi = htolel(0);
714
715 capability->vidParameters.lel_confServiceNum = htolel(0);
716
717 skinny_ChannelVideoParametersUnion_t *channelVideoParams = &(capability->vidParameters.capability);
718 {
719 if (skinnyFormat == SKINNY_CODEC_H261) {
720 channelVideoParams->h261.lel_temporalSpatialTradeOffCapability = htolel(1); // ??
721 channelVideoParams->h261.lel_stillImageTransmission = htolel(0); // ??
722 } else if (skinnyFormat == SKINNY_CODEC_H263) { //
723 channelVideoParams->h263.lel_capabilityBitfield = htolel(0); // ??
724 channelVideoParams->h263.lel_annexNandWFutureUse = htolel(0); // ??
725 } else if (skinnyFormat == SKINNY_CODEC_H263P) { // H263P / aka:Vieo / H263-1998
726 //CIF=1,QCIF=1
727 channelVideoParams->h263P.lel_modelNumber = htolel(0); // ??
728 channelVideoParams->h263P.lel_bandwidth = htolel(0); // ?? 90000
729 } else if (skinnyFormat == SKINNY_CODEC_H264) { // aka: MPEG4-AVC
730 channelVideoParams->h264.lel_profile = htolel(64); // should be taken from UpdateCapabilitiesMessage
731 channelVideoParams->h264.lel_level = htolel(43); // should be taken from UpdateCapabilitiesMessage
732 channelVideoParams->h264.lel_customMaxMBPS = htolel(40500); // should be taken from UpdateCapabilitiesMessage
733 channelVideoParams->h264.lel_customMaxFS = htolel(1620); // should be taken from UpdateCapabilitiesMessage
734 channelVideoParams->h264.lel_customMaxDPB = htolel(8100); // should be taken from UpdateCapabilitiesMessage
735 channelVideoParams->h264.lel_customMaxBRandCPB = htolel(10000); // should be taken from UpdateCapabilitiesMessage
736 } else {
737 // error
738 }
739 }
740 }
741 // Leave empty for now, until we find out more about encryption
742 //msg->data.OpenMultiMediaChannelMessage.v3.RxEncryptionInfo = {0};
743 msg->data.OpenMultiMediaChannelMessage.v3.lel_streamPassThroughID = htolel(channel->passthrupartyid);
744 msg->data.OpenMultiMediaChannelMessage.v3.lel_associatedStreamID = htolel(channel->callid); // We should use a random number and link it up
745 // with the MultiMediaTransmission
746 //sccp_dump_msg(msg);
747 sccp_dev_send(device, msg);
748 }
749 /*!
750 * \brief Send Open MultiMediaChannel Message (V12)
751 */
sccp_protocol_sendOpenMultiMediaChannelV12(constDevicePtr device,constChannelPtr channel,skinny_codec_t skinnyFormat,int payloadType,uint8_t lineInstance,int bitRate)752 static void sccp_protocol_sendOpenMultiMediaChannelV12(constDevicePtr device, constChannelPtr channel, skinny_codec_t skinnyFormat, int payloadType, uint8_t lineInstance, int bitRate)
753 {
754 sccp_msg_t *msg = sccp_build_packet(OpenMultiMediaChannelMessage, sizeof(msg->data.OpenMultiMediaChannelMessage.v12));
755
756 msg->data.OpenMultiMediaChannelMessage.v12.lel_conferenceID = htolel(channel->callid);
757 msg->data.OpenMultiMediaChannelMessage.v12.lel_passThruPartyID = htolel(channel->passthrupartyid);
758 msg->data.OpenMultiMediaChannelMessage.v12.lel_codecType = htolel(skinnyFormat);
759 //msg->data.OpenMultiMediaChannelMessage.v12.lel_codecType = htolel(channel->rtp.video.reception.format);
760 msg->data.OpenMultiMediaChannelMessage.v12.lel_lineInstance = htolel(lineInstance);
761 msg->data.OpenMultiMediaChannelMessage.v12.lel_callReference = htolel(channel->callid);
762
763 msg->data.OpenMultiMediaChannelMessage.v12.payloadType.lel_payload_rfc_number = htolel(0);
764 msg->data.OpenMultiMediaChannelMessage.v12.payloadType.lel_payloadType = htolel(payloadType);
765
766 msg->data.OpenMultiMediaChannelMessage.v12.lel_isConferenceCreator = htolel(0);
767
768 skinny_OpenMultiMediaReceiveChannelUnion_t *capability = &(msg->data.OpenMultiMediaChannelMessage.v12.capability);
769 {
770 capability->vidParameters.lel_bitRate = htolel(bitRate);
771 capability->vidParameters.lel_pictureFormatCount = htolel(1);
772
773 capability->vidParameters.pictureFormat[0].format = htolel(4); // should be taken from UpdateCapabilitiesMessage
774 capability->vidParameters.pictureFormat[0].mpi = htolel(1); // should be taken from UpdateCapabilitiesMessage
775 capability->vidParameters.pictureFormat[1].format = htolel(2);
776 capability->vidParameters.pictureFormat[1].mpi = htolel(1);
777 capability->vidParameters.pictureFormat[2].format = htolel(1);
778 capability->vidParameters.pictureFormat[2].mpi = htolel(1);
779 capability->vidParameters.pictureFormat[3].format = htolel(0);
780 capability->vidParameters.pictureFormat[3].mpi = htolel(1);
781 //capability->vidParameters.pictureFormat[4].format = htolel(0);
782 //capability->vidParameters.pictureFormat[4].mpi = htolel(0);
783
784 capability->vidParameters.lel_confServiceNum = htolel(0);
785
786 skinny_ChannelVideoParametersUnion_t *channelVideoParams = &(capability->vidParameters.capability);
787 {
788 if (skinnyFormat == SKINNY_CODEC_H261) {
789 channelVideoParams->h261.lel_temporalSpatialTradeOffCapability = htolel(1); // ??
790 channelVideoParams->h261.lel_stillImageTransmission = htolel(0); // ??
791 } else if (skinnyFormat == SKINNY_CODEC_H263) { //
792 channelVideoParams->h263.lel_capabilityBitfield = htolel(0); // ??
793 channelVideoParams->h263.lel_annexNandWFutureUse = htolel(0); // ??
794 } else if (skinnyFormat == SKINNY_CODEC_H263P) { // H263P / aka:Vieo / H263-1998
795 //CIF=1,QCIF=1
796 channelVideoParams->h263P.lel_modelNumber = htolel(0); // ??
797 channelVideoParams->h263P.lel_bandwidth = htolel(0); // ?? 90000
798 } else if (skinnyFormat == SKINNY_CODEC_H264) { // aka: MPEG4-AVC
799 channelVideoParams->h264.lel_profile = htolel(64); // should be taken from UpdateCapabilitiesMessage
800 channelVideoParams->h264.lel_level = htolel(43); // should be taken from UpdateCapabilitiesMessage
801 channelVideoParams->h264.lel_customMaxMBPS = htolel(40500); // should be taken from UpdateCapabilitiesMessage
802 channelVideoParams->h264.lel_customMaxFS = htolel(1620); // should be taken from UpdateCapabilitiesMessage
803 channelVideoParams->h264.lel_customMaxDPB = htolel(8100); // should be taken from UpdateCapabilitiesMessage
804 channelVideoParams->h264.lel_customMaxBRandCPB = htolel(10000); // should be taken from UpdateCapabilitiesMessage
805 } else {
806 // error
807 }
808 }
809 }
810 // Leave empty for now, until we find out more about encryption
811 //msg->data.OpenMultiMediaChannelMessage.v12.RxEncryptionInfo = {0};
812 msg->data.OpenMultiMediaChannelMessage.v12.lel_streamPassThroughID = htolel(channel->passthrupartyid);
813 msg->data.OpenMultiMediaChannelMessage.v12.lel_associatedStreamID = htolel(channel->callid); // We should use a random number and link it up
814 // with the MultiMediaTransmission
815
816 /* Source Ip Address */
817 struct sockaddr_storage sas;
818 if (device->directrtp) {
819 sccp_rtp_getPeer(&channel->rtp.video, &sas);
820 } else {
821 sccp_rtp_getUs(&channel->rtp.video, &sas);
822 }
823 sccp_netsock_ipv4_mapped(&sas, &sas);
824
825 if (sas.ss_family == AF_INET) {
826 struct sockaddr_in *in = (struct sockaddr_in *) &sas;
827 memcpy(&msg->data.OpenMultiMediaChannelMessage.v12.bel_sourceIpAddr, &in->sin_addr, 4);
828 } else {
829 // error
830 }
831 msg->data.OpenMultiMediaChannelMessage.v12.lel_sourcePortNumber=htolel(sccp_netsock_getPort(&sas));
832
833 //sccp_dump_msg(msg);
834 sccp_dev_send(device, msg);
835 }
836 /*!
837 * \brief Send Open MultiMediaChannel Message (V17)
838 */
sccp_protocol_sendOpenMultiMediaChannelV17(constDevicePtr device,constChannelPtr channel,skinny_codec_t skinnyFormat,int payloadType,uint8_t lineInstance,int bitRate)839 static void sccp_protocol_sendOpenMultiMediaChannelV17(constDevicePtr device, constChannelPtr channel, skinny_codec_t skinnyFormat, int payloadType, uint8_t lineInstance, int bitRate)
840 {
841 sccp_msg_t *msg = sccp_build_packet(OpenMultiMediaChannelMessage, sizeof(msg->data.OpenMultiMediaChannelMessage.v17));
842
843 msg->data.OpenMultiMediaChannelMessage.v17.lel_conferenceID = htolel(channel->callid);
844 msg->data.OpenMultiMediaChannelMessage.v17.lel_passThruPartyID = htolel(channel->passthrupartyid);
845 msg->data.OpenMultiMediaChannelMessage.v17.lel_codecType = htolel(skinnyFormat);
846 //msg->data.OpenMultiMediaChannelMessage.v17.lel_codecType = htolel(channel->rtp.video.reception.format);
847 msg->data.OpenMultiMediaChannelMessage.v17.lel_lineInstance = htolel(lineInstance);
848 msg->data.OpenMultiMediaChannelMessage.v17.lel_callReference = htolel(channel->callid);
849
850 msg->data.OpenMultiMediaChannelMessage.v17.payloadType.lel_payload_rfc_number = htolel(0);
851 msg->data.OpenMultiMediaChannelMessage.v17.payloadType.lel_payloadType = htolel(payloadType);
852
853 msg->data.OpenMultiMediaChannelMessage.v17.lel_isConferenceCreator = htolel(0);
854
855
856 skinny_OpenMultiMediaReceiveChannelUnion_t *capability = &(msg->data.OpenMultiMediaChannelMessage.v17.capability);
857 {
858 capability->vidParameters.lel_bitRate = htolel(bitRate);
859 capability->vidParameters.lel_pictureFormatCount = htolel(1);
860
861 capability->vidParameters.pictureFormat[0].format = htolel(4); // should be taken from UpdateCapabilitiesMessage
862 /*
863 MPI = Minimum Picture interval. 1=means 29.7 frames, 2=halfs that to 14.9.
864 If the receiver does not specify the picture size/MPI optional parameter, then it SHOULD be ready to receive QCIF resolution with MPI=1.
865 */
866 capability->vidParameters.pictureFormat[0].format = htolel(4); // should be taken from UpdateCapabilitiesMessage
867 capability->vidParameters.pictureFormat[0].mpi = htolel(1); // should be taken from UpdateCapabilitiesMessage
868 capability->vidParameters.pictureFormat[1].format = htolel(2);
869 capability->vidParameters.pictureFormat[1].mpi = htolel(1);
870 capability->vidParameters.pictureFormat[2].format = htolel(1);
871 capability->vidParameters.pictureFormat[2].mpi = htolel(1);
872 capability->vidParameters.pictureFormat[3].format = htolel(0);
873 capability->vidParameters.pictureFormat[3].mpi = htolel(1);
874 //capability->vidParameters.pictureFormat[4].format = htolel(0);
875 //capability->vidParameters.pictureFormat[4].mpi = htolel(0);
876
877 capability->vidParameters.lel_confServiceNum = htolel(0);
878
879 skinny_ChannelVideoParametersUnion_t *channelVideoParams = &(capability->vidParameters.capability);
880 {
881 if (skinnyFormat == SKINNY_CODEC_H261) {
882 channelVideoParams->h261.lel_temporalSpatialTradeOffCapability = htolel(1); // ??
883 channelVideoParams->h261.lel_stillImageTransmission = htolel(0); // ??
884 } else if (skinnyFormat == SKINNY_CODEC_H263) { // https://tools.ietf.org/html/rfc4629
885 channelVideoParams->h263.lel_capabilityBitfield = htolel(0); // ??
886 channelVideoParams->h263.lel_annexNandWFutureUse = htolel(0); // ??
887 } else if (skinnyFormat == SKINNY_CODEC_H263P) { // H263P / aka:Vieo / H263-1998
888 //CIF=1,QCIF=1
889 channelVideoParams->h263P.lel_modelNumber = htolel(0); // ??
890 channelVideoParams->h263P.lel_bandwidth = htolel(0); // ?? 90000
891 } else if (skinnyFormat == SKINNY_CODEC_H264) { // aka: MPEG4-AVC
892 /*
893 PROFILE: profile number, in the range 0 through 10,
894 specifying the supported H.263 annexes/subparts based on H.263
895 annex X [H263]. The annexes supported in each profile are listed
896 in table X.1 of H.263 annex X. If no profile or H.263 annex is
897 specified, then the stream is Baseline H.263 (profile 0 of H.263
898 annex X).
899 */
900 channelVideoParams->h264.lel_profile = htolel(64); // should be taken from UpdateCapabilitiesMessage
901 /*
902 LEVEL: Level of bitstream operation, in the range 0 through 100,
903 specifying the level of computational complexity of the decoding
904 process. The level are described in table X.2 of H.263 annex X.
905 */
906 channelVideoParams->h264.lel_level = htolel(43); // should be taken from UpdateCapabilitiesMessage
907 channelVideoParams->h264.lel_customMaxMBPS = htolel(40500); // should be taken from UpdateCapabilitiesMessage
908 channelVideoParams->h264.lel_customMaxFS = htolel(1620); // should be taken from UpdateCapabilitiesMessage
909 channelVideoParams->h264.lel_customMaxDPB = htolel(8100); // should be taken from UpdateCapabilitiesMessage
910 channelVideoParams->h264.lel_customMaxBRandCPB = htolel(10000); // should be taken from UpdateCapabilitiesMessage
911 } else {
912 // error
913 }
914 }
915 }
916 // Leave empty for now, until we find out more about encryption
917 //msg->data.OpenMultiMediaChannelMessage.v17.RxEncryptionInfo = {0};
918 msg->data.OpenMultiMediaChannelMessage.v17.lel_streamPassThroughID = htolel(channel->passthrupartyid);
919 msg->data.OpenMultiMediaChannelMessage.v17.lel_associatedStreamID = htolel(channel->callid); // We should use a random number and link it up
920 // with the MultiMediaTransmission
921
922 /* Source Ip Address */
923 struct sockaddr_storage sas;
924 if (device->directrtp) {
925 sccp_rtp_getPeer(&channel->rtp.video, &sas);
926 } else {
927 sccp_rtp_getUs(&channel->rtp.video, &sas);
928 }
929 sccp_netsock_ipv4_mapped(&sas, &sas);
930
931 if (sas.ss_family == AF_INET6) {
932 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &sas;
933 msg->data.OpenMultiMediaChannelMessage.v17.sourceIpAddr.lel_ipAddrType = htolel(SKINNY_IPADDR_IPV6);
934
935 // Also take into account that we could be using IPv46 (ie: both of them)
936 if (sccp_netsock_is_mapped_IPv4(&sas)) {
937 msg->data.OpenMultiMediaChannelMessage.v17.lel_requestedIpAddrType = htolel(SKINNY_IPADDR_IPV46);
938 } else {
939 msg->data.OpenMultiMediaChannelMessage.v17.lel_requestedIpAddrType = htolel(SKINNY_IPADDR_IPV6);
940 }
941 memcpy(&msg->data.OpenMultiMediaChannelMessage.v17.sourceIpAddr.stationIpAddr, &in6->sin6_addr, 16);
942 } else {
943 struct sockaddr_in *in = (struct sockaddr_in *) &sas;
944 msg->data.OpenMultiMediaChannelMessage.v17.sourceIpAddr.lel_ipAddrType = htolel(SKINNY_IPADDR_IPV4);
945 msg->data.OpenMultiMediaChannelMessage.v17.lel_requestedIpAddrType = htolel(SKINNY_IPADDR_IPV4);
946 memcpy(&msg->data.OpenMultiMediaChannelMessage.v17.sourceIpAddr.stationIpAddr, &in->sin_addr, 4);
947 }
948 msg->data.OpenMultiMediaChannelMessage.v17.lel_sourcePortNumber=htolel(sccp_netsock_getPort(&sas));
949
950 //sccp_dump_msg(msg);
951 sccp_dev_send(device, msg);
952 }
953
954 /*!
955 * \brief Send Start Media Transmission (V3)
956 */
sccp_protocol_sendStartMediaTransmissionV3(constDevicePtr device,constChannelPtr channel)957 static void sccp_protocol_sendStartMediaTransmissionV3(constDevicePtr device, constChannelPtr channel)
958 {
959 sccp_msg_t *msg = sccp_build_packet(StartMediaTransmission, sizeof(msg->data.StartMediaTransmission.v3));
960
961 uint framing = iPbx.get_codec_framing ? iPbx.get_codec_framing(channel) : 20;
962 uint dtmf_payload_code = iPbx.get_dtmf_payload_code ? iPbx.get_dtmf_payload_code(channel) : 101;
963
964 msg->data.StartMediaTransmission.v3.lel_conferenceId = htolel(channel->callid);
965 msg->data.StartMediaTransmission.v3.lel_passThruPartyId = htolel(channel->passthrupartyid);
966 msg->data.StartMediaTransmission.v3.lel_callReference = htolel(channel->callid);
967 msg->data.StartMediaTransmission.v3.lel_millisecondPacketSize = htolel(framing);
968 //msg->data.StartMediaTransmission.v3.lel_payloadType = htolel(channel->rtp.audio.transmission.format);
969 msg->data.StartMediaTransmission.v3.lel_codecType = htolel(channel->rtp.audio.transmission.format);
970 msg->data.StartMediaTransmission.v3.lel_precedenceValue = htolel((uint32_t)device->audio_tos);
971 msg->data.StartMediaTransmission.v3.lel_ssValue = htolel(channel->line->silencesuppression); // Silence supression
972 msg->data.StartMediaTransmission.v3.lel_maxFramesPerPacket = htolel(0);
973 msg->data.StartMediaTransmission.v3.lel_RFC2833Type = htolel(dtmf_payload_code);
974 msg->data.StartMediaTransmission.v3.lel_dtmfType = htolel(10);;
975
976 if (channel->rtp.audio.phone_remote.ss_family == AF_INET) {
977 struct sockaddr_in *in = (struct sockaddr_in *) &channel->rtp.audio.phone_remote;
978
979 memcpy(&msg->data.StartMediaTransmission.v3.bel_remoteIpAddr, &in->sin_addr, 4);
980 } else {
981 /* \todo add warning */
982 }
983 msg->data.StartMediaTransmission.v3.lel_remotePortNumber = htolel(sccp_netsock_getPort(&channel->rtp.audio.phone_remote));
984
985 sccp_dev_send(device, msg);
986 }
987
988 /*!
989 * \brief Send Start Media Transmission (V17)
990 */
sccp_protocol_sendStartMediaTransmissionV17(constDevicePtr device,constChannelPtr channel)991 static void sccp_protocol_sendStartMediaTransmissionV17(constDevicePtr device, constChannelPtr channel)
992 {
993 sccp_msg_t *msg = sccp_build_packet(StartMediaTransmission, sizeof(msg->data.StartMediaTransmission.v17));
994
995 uint framing = iPbx.get_codec_framing ? iPbx.get_codec_framing(channel) : 20;
996 uint dtmf_payload_code = iPbx.get_dtmf_payload_code ? iPbx.get_dtmf_payload_code(channel) : 101;
997
998 msg->data.StartMediaTransmission.v17.lel_conferenceId = htolel(channel->callid);
999 msg->data.StartMediaTransmission.v17.lel_passThruPartyId = htolel(channel->passthrupartyid);
1000 msg->data.StartMediaTransmission.v17.lel_callReference = htolel(channel->callid);
1001 msg->data.StartMediaTransmission.v17.lel_millisecondPacketSize = htolel(framing);
1002 //msg->data.StartMediaTransmission.v17.lel_payloadType = htolel(channel->rtp.audio.transmission.format);
1003 msg->data.StartMediaTransmission.v17.lel_codecType = htolel(channel->rtp.audio.transmission.format);
1004 msg->data.StartMediaTransmission.v17.lel_precedenceValue = htolel((uint32_t)device->audio_tos);
1005 msg->data.StartMediaTransmission.v17.lel_ssValue = htolel(channel->line->silencesuppression); // Silence supression
1006 msg->data.StartMediaTransmission.v17.lel_maxFramesPerPacket = htolel(0);
1007 msg->data.StartMediaTransmission.v17.lel_RFC2833Type = htolel(dtmf_payload_code);
1008 msg->data.StartMediaTransmission.v17.lel_dtmfType = htolel(10);;
1009
1010 if (channel->rtp.audio.phone_remote.ss_family == AF_INET6) {
1011 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &channel->rtp.audio.phone_remote;
1012
1013 memcpy(&msg->data.StartMediaTransmission.v17.bel_remoteIpAddr, &in6->sin6_addr, 16);
1014 msg->data.StartMediaTransmission.v17.lel_ipv46 = htolel(1);
1015 } else {
1016 struct sockaddr_in *in = (struct sockaddr_in *) &channel->rtp.audio.phone_remote;
1017
1018 memcpy(&msg->data.StartMediaTransmission.v17.bel_remoteIpAddr, &in->sin_addr, 4);
1019 }
1020 msg->data.StartMediaTransmission.v17.lel_remotePortNumber = htolel(sccp_netsock_getPort(&channel->rtp.audio.phone_remote));
1021 sccp_dev_send(device, msg);
1022 }
1023
1024 /*!
1025 * \brief Send Start Media Transmission (v22)
1026 */
sccp_protocol_sendStartMediaTransmissionv22(constDevicePtr device,constChannelPtr channel)1027 static void sccp_protocol_sendStartMediaTransmissionv22(constDevicePtr device, constChannelPtr channel)
1028 {
1029 sccp_msg_t *msg = sccp_build_packet(StartMediaTransmission, sizeof(msg->data.StartMediaTransmission.v22));
1030
1031 uint framing = iPbx.get_codec_framing ? iPbx.get_codec_framing(channel) : 20;
1032 uint dtmf_payload_code = iPbx.get_dtmf_payload_code ? iPbx.get_dtmf_payload_code(channel) : 101;
1033
1034 msg->data.StartMediaTransmission.v22.lel_conferenceId = htolel(channel->callid);
1035 msg->data.StartMediaTransmission.v22.lel_passThruPartyId = htolel(channel->passthrupartyid);
1036 msg->data.StartMediaTransmission.v22.lel_callReference = htolel(channel->callid);
1037 msg->data.StartMediaTransmission.v22.lel_millisecondPacketSize = htolel(framing);
1038 //msg->data.StartMediaTransmission.v22.lel_payloadType = htolel(channel->rtp.audio.transmission.format);
1039 msg->data.StartMediaTransmission.v22.lel_codecType = htolel(channel->rtp.audio.transmission.format);
1040 msg->data.StartMediaTransmission.v22.lel_precedenceValue = htolel((uint32_t)device->audio_tos);
1041 msg->data.StartMediaTransmission.v22.lel_ssValue = htolel(channel->line->silencesuppression); // Silence supression
1042 msg->data.StartMediaTransmission.v22.lel_maxFramesPerPacket = htolel(0);
1043 msg->data.StartMediaTransmission.v22.lel_RFC2833Type = htolel(dtmf_payload_code);
1044 msg->data.StartMediaTransmission.v22.lel_dtmfType = htolel(10);;
1045
1046 if (channel->rtp.audio.phone_remote.ss_family == AF_INET6) {
1047 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &channel->rtp.audio.phone_remote;
1048
1049 memcpy(&msg->data.StartMediaTransmission.v22.bel_remoteIpAddr, &in6->sin6_addr, 16);
1050 msg->data.StartMediaTransmission.v22.lel_ipv46 = htolel(1);
1051 } else {
1052 struct sockaddr_in *in = (struct sockaddr_in *) &channel->rtp.audio.phone_remote;
1053
1054 memcpy(&msg->data.StartMediaTransmission.v22.bel_remoteIpAddr, &in->sin_addr, 4);
1055 }
1056 msg->data.StartMediaTransmission.v22.lel_remotePortNumber = htolel(sccp_netsock_getPort(&channel->rtp.audio.phone_remote));
1057 sccp_dev_send(device, msg);
1058 }
1059
1060 /*!
1061 * \brief Send Start MultiMedia Transmission (V3)
1062 */
sccp_protocol_sendStartMultiMediaTransmissionV3(constDevicePtr device,constChannelPtr channel,int payloadType,int bitRate)1063 static void sccp_protocol_sendStartMultiMediaTransmissionV3(constDevicePtr device, constChannelPtr channel, int payloadType, int bitRate)
1064 {
1065 sccp_msg_t *msg = sccp_build_packet(StartMultiMediaTransmission, sizeof(msg->data.StartMultiMediaTransmission.v3));
1066 //uint payloadType = sccp_rtp_get_payloadType(&channel->rtp.video, video->transmission.format);
1067
1068 msg->data.StartMultiMediaTransmission.v3.lel_conferenceID = htolel(channel->callid);
1069 msg->data.StartMultiMediaTransmission.v3.lel_passThruPartyId = htolel(channel->passthrupartyid);
1070 //msg->data.StartMultiMediaTransmission.v3.lel_payloadCapability = htolel(channel->rtp.video.transmission.format);
1071 msg->data.StartMultiMediaTransmission.v3.lel_codecType = htolel(channel->rtp.video.transmission.format);
1072 msg->data.StartMultiMediaTransmission.v3.lel_callReference = htolel(channel->callid);
1073 msg->data.StartMultiMediaTransmission.v3.lel_payload_rfc_number = htolel(0);
1074 msg->data.StartMultiMediaTransmission.v3.lel_payloadType = htolel(payloadType);
1075 msg->data.StartMultiMediaTransmission.v3.lel_DSCPValue = htolel(136);
1076 msg->data.StartMultiMediaTransmission.v3.videoParameter.bitRate = htolel(bitRate);
1077 //msg->data.StartMultiMediaTransmission.v3.videoParameter.pictureFormatCount = htolel(0);
1078 //msg->data.StartMultiMediaTransmission.v3.videoParameter.pictureFormat[0].format = htolel(4);
1079 //msg->data.StartMultiMediaTransmission.v3.videoParameter.pictureFormat[0].mpi = htolel(30);
1080 msg->data.StartMultiMediaTransmission.v3.videoParameter.profile = htolel(0x40);
1081 msg->data.StartMultiMediaTransmission.v3.videoParameter.level = htolel(0x32); /* has to be >= 15 to work with 7985 */
1082 msg->data.StartMultiMediaTransmission.v3.videoParameter.macroblockspersec = htolel(40500);
1083 msg->data.StartMultiMediaTransmission.v3.videoParameter.macroblocksperframe = htolel(1620);
1084 msg->data.StartMultiMediaTransmission.v3.videoParameter.decpicbuf = htolel(8100);
1085 msg->data.StartMultiMediaTransmission.v3.videoParameter.brandcpb = htolel(10000);
1086 msg->data.StartMultiMediaTransmission.v3.videoParameter.confServiceNum = htolel(channel->callid);
1087 msg->data.StartMultiMediaTransmission.v3.lel_remotePortNumber = htolel(sccp_netsock_getPort(&channel->rtp.video.phone_remote));
1088 if (channel->rtp.video.phone_remote.ss_family == AF_INET) {
1089 struct sockaddr_in *in = (struct sockaddr_in *) &channel->rtp.video.phone_remote;
1090
1091 memcpy(&msg->data.StartMultiMediaTransmission.v3.bel_remoteIpAddr, &in->sin_addr, 4);
1092 } else {
1093 /* \todo add warning */
1094 }
1095
1096 //sccp_dump_msg(msg);
1097 sccp_dev_send(device, msg);
1098 }
1099
1100 /*!
1101 * \brief Send Start MultiMedia Transmission (V17)
1102 */
sccp_protocol_sendStartMultiMediaTransmissionV17(constDevicePtr device,constChannelPtr channel,int payloadType,int bitRate)1103 static void sccp_protocol_sendStartMultiMediaTransmissionV17(constDevicePtr device, constChannelPtr channel, int payloadType, int bitRate)
1104 {
1105 sccp_msg_t *msg = sccp_build_packet(StartMultiMediaTransmission, sizeof(msg->data.StartMultiMediaTransmission.v17));
1106
1107 msg->data.StartMultiMediaTransmission.v17.lel_conferenceID = htolel(channel->callid);
1108 msg->data.StartMultiMediaTransmission.v17.lel_passThruPartyId = htolel(channel->passthrupartyid);
1109 //msg->data.StartMultiMediaTransmission.v17.lel_payloadCapability = htolel(channel->rtp.video.transmission.format);
1110 msg->data.StartMultiMediaTransmission.v17.lel_codecType = htolel(channel->rtp.video.transmission.format);
1111 msg->data.StartMultiMediaTransmission.v17.lel_callReference = htolel(channel->callid);
1112 msg->data.StartMultiMediaTransmission.v17.lel_payload_rfc_number = htolel(0);
1113 msg->data.StartMultiMediaTransmission.v17.lel_payloadType = htolel(payloadType);
1114 msg->data.StartMultiMediaTransmission.v17.lel_DSCPValue = htolel(136);
1115 msg->data.StartMultiMediaTransmission.v17.videoParameter.confServiceNum = htolel(channel->callid);
1116 msg->data.StartMultiMediaTransmission.v17.videoParameter.bitRate = htolel(bitRate);
1117 //msg->data.StartMultiMediaTransmission.v17.videoParameter.pictureFormatCount = htolel(1);
1118 //msg->data.StartMultiMediaTransmission.v17.videoParameter.pictureFormat[0].format = htolel(4);
1119 //msg->data.StartMultiMediaTransmission.v17.videoParameter.pictureFormat[0].mpi = htolel(1);
1120 msg->data.StartMultiMediaTransmission.v17.videoParameter.profile = htolel(64);
1121 msg->data.StartMultiMediaTransmission.v17.videoParameter.level = htolel(50);
1122 msg->data.StartMultiMediaTransmission.v17.videoParameter.macroblockspersec = htolel(40500);
1123 msg->data.StartMultiMediaTransmission.v17.videoParameter.macroblocksperframe = htolel(1620);
1124 msg->data.StartMultiMediaTransmission.v17.videoParameter.decpicbuf = htolel(8100);
1125 msg->data.StartMultiMediaTransmission.v17.videoParameter.brandcpb = htolel(10000);
1126 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy1 = htolel(1);
1127 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy2 = htolel(2);
1128 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy3 = htolel(3);
1129 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy4 = htolel(4);
1130 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy5 = htolel(5);
1131 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy6 = htolel(6);
1132 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy7 = htolel(7);
1133 //msg->data.StartMultiMediaTransmission.v17.videoParameter.dummy8 = htolel(8);
1134
1135 msg->data.StartMultiMediaTransmission.v17.lel_remotePortNumber = htolel(sccp_netsock_getPort(&channel->rtp.video.phone_remote));
1136 if (channel->rtp.video.phone_remote.ss_family == AF_INET6) {
1137 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &channel->rtp.video.phone_remote;
1138
1139 memcpy(&msg->data.StartMultiMediaTransmission.v17.bel_remoteIpAddr, &in6->sin6_addr, 16);
1140 msg->data.StartMultiMediaTransmission.v17.lel_ipv46 = htolel(1);
1141 } else {
1142 struct sockaddr_in *in = (struct sockaddr_in *) &channel->rtp.video.phone_remote;
1143
1144 memcpy(&msg->data.StartMultiMediaTransmission.v17.bel_remoteIpAddr, &in->sin_addr, 4);
1145 }
1146 //sccp_dump_msg(msg);
1147 sccp_dev_send(device, msg);
1148 }
1149
1150 /* fastPictureUpdate */
sccp_protocol_sendMultiMediaCommand(constDevicePtr device,constChannelPtr channel,skinny_miscCommandType_t command)1151 static void sccp_protocol_sendMultiMediaCommand(constDevicePtr device, constChannelPtr channel, skinny_miscCommandType_t command)
1152 {
1153 sccp_msg_t *msg = NULL;
1154
1155 REQ(msg, MiscellaneousCommandMessage);
1156
1157 msg->data.MiscellaneousCommandMessage.lel_conferenceId = htolel(channel->callid);
1158 msg->data.MiscellaneousCommandMessage.lel_passThruPartyId = htolel(channel->passthrupartyid);
1159 msg->data.MiscellaneousCommandMessage.lel_callReference = htolel(channel->callid);
1160 msg->data.MiscellaneousCommandMessage.lel_miscCommandType = htolel(command);
1161
1162 sccp_dev_send(device, msg);
1163 }
1164
1165 /* done - fastPictureUpdate */
1166
1167 /* sendUserToDeviceData Message */
1168
1169 /*!
1170 * \brief Send User To Device Message (V1)
1171 */
sccp_protocol_sendUserToDeviceDataVersion1Message(constDevicePtr device,uint32_t appID,uint32_t lineInstance,uint32_t callReference,uint32_t transactionID,const char * xmlData,uint8_t priority)1172 static void sccp_protocol_sendUserToDeviceDataVersion1Message(constDevicePtr device, uint32_t appID, uint32_t lineInstance, uint32_t callReference, uint32_t transactionID, const char *xmlData, uint8_t priority)
1173 {
1174 int data_len = strlen(xmlData);
1175 int msg_len = 0;
1176 int hdr_len = 0;
1177
1178 if (device->protocolversion > 17) {
1179 int segment = 0;
1180
1181 sccp_msg_t *msg = NULL;
1182 hdr_len = sizeof(msg->data.UserToDeviceDataVersion1Message);
1183 int Sequence = 0x0000;
1184 int xmlDataStart = 0;
1185
1186 while (data_len) {
1187 if (data_len > StationMaxXMLMessage) {
1188 msg_len = StationMaxXMLMessage;
1189 } else {
1190 msg_len = data_len;
1191 Sequence = 0x0002;
1192 }
1193 data_len -= msg_len;
1194 msg = sccp_build_packet(UserToDeviceDataVersion1Message, hdr_len + msg_len);
1195 if (!msg) {
1196 pbx_log(LOG_ERROR, SS_Memory_Allocation_Error, "SCCP");
1197 return;
1198 }
1199 msg->data.UserToDeviceDataVersion1Message.lel_appID = htolel(appID);
1200 msg->data.UserToDeviceDataVersion1Message.lel_lineInstance = htolel(lineInstance);
1201 msg->data.UserToDeviceDataVersion1Message.lel_callReference = htolel(callReference);
1202 msg->data.UserToDeviceDataVersion1Message.lel_transactionID = htolel(transactionID);
1203 msg->data.UserToDeviceDataVersion1Message.lel_displayPriority = htolel(priority);
1204 msg->data.UserToDeviceDataVersion1Message.lel_dataLength = htolel(msg_len);
1205 msg->data.UserToDeviceDataVersion1Message.lel_sequenceFlag = htolel(Sequence);
1206 msg->data.UserToDeviceDataVersion1Message.lel_conferenceID = htolel(callReference);
1207 msg->data.UserToDeviceDataVersion1Message.lel_appInstanceID = htolel(appID);
1208 msg->data.UserToDeviceDataVersion1Message.lel_routing = htolel(1);
1209 if (Sequence == 0x0000) {
1210 Sequence = 0x0001;
1211 }
1212
1213 if (msg_len) {
1214 memcpy(&msg->data.UserToDeviceDataVersion1Message.data, xmlData + xmlDataStart, msg_len);
1215 xmlDataStart += msg_len;
1216 }
1217
1218 sccp_dev_send(device, msg);
1219 sccp_log(DEBUGCAT_HIGH) (VERBOSE_PREFIX_1 "%s: (sccp_protocol_sendUserToDeviceDataVersion1Message) Message sent to device (hdr_len: %d, msglen: %d/%d, msg-size: %d).\n", DEV_ID_LOG(device), hdr_len, msg_len, (int) strlen(xmlData), hdr_len + msg_len);
1220 segment++;
1221 }
1222 } else if (data_len < StationMaxXMLMessage) {
1223 sccp_msg_t *msg = NULL;
1224
1225 hdr_len = sizeof(msg->data.UserToDeviceDataVersion1Message);
1226 msg_len = data_len;
1227
1228 msg = sccp_build_packet(UserToDeviceDataVersion1Message, hdr_len + msg_len);
1229 msg->data.UserToDeviceDataVersion1Message.lel_appID = htolel(appID);
1230 msg->data.UserToDeviceDataVersion1Message.lel_lineInstance = htolel(lineInstance);
1231 msg->data.UserToDeviceDataVersion1Message.lel_callReference = htolel(callReference);
1232 msg->data.UserToDeviceDataVersion1Message.lel_transactionID = htolel(transactionID);
1233 msg->data.UserToDeviceDataVersion1Message.lel_sequenceFlag = htolel(0x0002);
1234 msg->data.UserToDeviceDataVersion1Message.lel_displayPriority = htolel(priority);
1235 msg->data.UserToDeviceDataVersion1Message.lel_dataLength = htolel(msg_len);
1236
1237 if (msg_len) {
1238 memcpy(&msg->data.UserToDeviceDataVersion1Message.data, xmlData, msg_len);
1239 }
1240 sccp_dev_send(device, msg);
1241 sccp_log(DEBUGCAT_HIGH) (VERBOSE_PREFIX_1 "%s: (sccp_protocol_sendUserToDeviceDataVersion1Message) Message sent to device (hdr_len: %d, msglen: %d, msg-size: %d).\n", DEV_ID_LOG(device), hdr_len, msg_len, hdr_len + msg_len);
1242 } else {
1243 sccp_log(DEBUGCAT_CORE) (VERBOSE_PREFIX_1 "%s: (sccp_protocol_sendUserToDeviceDataVersion1Message) Message to large to send to device (msg-size: %d). Skipping !\n", DEV_ID_LOG(device), data_len);
1244 }
1245 }
1246
1247 /* done - sendUserToDeviceData */
1248
1249 /* sendConnectionStatisticsReq Message */
1250 /*!
1251 * \brief Send Start MultiMedia Transmission (V3)
1252 */
sccp_protocol_sendConnectionStatisticsReqV3(constDevicePtr device,constChannelPtr channel,uint8_t clear)1253 static void sccp_protocol_sendConnectionStatisticsReqV3(constDevicePtr device, constChannelPtr channel, uint8_t clear)
1254 {
1255 sccp_msg_t *msg = sccp_build_packet(ConnectionStatisticsReq, sizeof(msg->data.ConnectionStatisticsReq.v3));
1256 if (channel->calltype == SKINNY_CALLTYPE_OUTBOUND) {
1257 iCallInfo.Getter(sccp_channel_getCallInfo(channel), SCCP_CALLINFO_CALLEDPARTY_NUMBER, &msg->data.ConnectionStatisticsReq.v3.DirectoryNumber, SCCP_CALLINFO_KEY_SENTINEL);
1258 } else {
1259 iCallInfo.Getter(sccp_channel_getCallInfo(channel), SCCP_CALLINFO_CALLINGPARTY_NUMBER, &msg->data.ConnectionStatisticsReq.v3.DirectoryNumber, SCCP_CALLINFO_KEY_SENTINEL);
1260 }
1261 msg->data.ConnectionStatisticsReq.v3.lel_callReference = htolel((channel) ? channel->callid : 0);
1262 msg->data.ConnectionStatisticsReq.v3.lel_StatsProcessing = htolel(clear);
1263 sccp_dev_send(device, msg);
1264 }
1265
1266 /*!
1267 * \brief Send Start MultiMedia Transmission (V17)
1268 */
sccp_protocol_sendConnectionStatisticsReqV19(constDevicePtr device,constChannelPtr channel,uint8_t clear)1269 static void sccp_protocol_sendConnectionStatisticsReqV19(constDevicePtr device, constChannelPtr channel, uint8_t clear)
1270 {
1271 sccp_msg_t *msg = sccp_build_packet(ConnectionStatisticsReq, sizeof(msg->data.ConnectionStatisticsReq.v19));
1272
1273 if (channel->calltype == SKINNY_CALLTYPE_OUTBOUND) {
1274 iCallInfo.Getter(sccp_channel_getCallInfo(channel), SCCP_CALLINFO_CALLEDPARTY_NUMBER, &msg->data.ConnectionStatisticsReq.v19.DirectoryNumber, SCCP_CALLINFO_KEY_SENTINEL);
1275 } else {
1276 iCallInfo.Getter(sccp_channel_getCallInfo(channel), SCCP_CALLINFO_CALLINGPARTY_NUMBER, &msg->data.ConnectionStatisticsReq.v19.DirectoryNumber, SCCP_CALLINFO_KEY_SENTINEL);
1277 }
1278 msg->data.ConnectionStatisticsReq.v19.lel_callReference = htolel((channel) ? channel->callid : 0);
1279 msg->data.ConnectionStatisticsReq.v19.lel_StatsProcessing = htolel(clear);
1280 sccp_dev_send(device, msg);
1281 }
1282 /* done - sendUserToDeviceData */
1283
1284
1285 /* sendPortRequest */
1286 /*!
1287 * \brief Send PortRequest (V3)
1288 */
sccp_protocol_sendPortRequest(constDevicePtr device,constChannelPtr channel,skinny_mediaTransportType_t mediaTransportType,skinny_mediaType_t mediaType)1289 static void sccp_protocol_sendPortRequest(constDevicePtr device, constChannelPtr channel, skinny_mediaTransportType_t mediaTransportType, skinny_mediaType_t mediaType)
1290 {
1291 struct sockaddr_storage sas;
1292 memcpy(&sas, &channel->rtp.audio.phone_remote, sizeof(struct sockaddr_storage));
1293 sccp_msg_t *msg = sccp_build_packet(PortRequestMessage, sizeof(msg->data.PortRequestMessage));
1294
1295 msg->data.PortRequestMessage.lel_conferenceId = htolel(channel->callid);
1296 msg->data.PortRequestMessage.lel_callReference = htolel(channel->callid);
1297 msg->data.PortRequestMessage.lel_passThruPartyId = htolel(channel->passthrupartyid);
1298 msg->data.PortRequestMessage.lel_mediaTransportType = htolel(mediaTransportType);
1299 msg->data.PortRequestMessage.lel_ipv46 = htolel(sccp_netsock_is_IPv6(&sas) ? 1 : 0);
1300 msg->data.PortRequestMessage.lel_mediaType = htolel(mediaType);
1301
1302 sccp_dev_send(device, msg);
1303 }
1304 /* done - sendPortRequest */
1305
1306 /* sendPortClose */
1307 /*!
1308 * \brief Send PortClose
1309 */
sccp_protocol_sendPortClose(constDevicePtr device,constChannelPtr channel,skinny_mediaType_t mediaType)1310 static void sccp_protocol_sendPortClose(constDevicePtr device, constChannelPtr channel, skinny_mediaType_t mediaType)
1311 {
1312 if (device->protocol && device->protocol->version >= 11) {
1313 sccp_msg_t *msg = sccp_build_packet(PortCloseMessage, sizeof(msg->data.PortCloseMessage));
1314 msg->data.PortCloseMessage.lel_conferenceId = htolel(channel->callid);
1315 msg->data.PortCloseMessage.lel_passThruPartyId = htolel(channel->passthrupartyid);
1316 msg->data.PortCloseMessage.lel_callReference = htolel(channel->callid);
1317 msg->data.PortCloseMessage.lel_mediaType = htolel(mediaType);
1318 sccp_dev_send(device, msg);
1319 }
1320 }
1321 /* done - sendPortClose */
1322
1323 /*! \todo need a protocol implementation for ConnectionStatisticsReq using Version 19 and higher */
1324
1325 /*! \todo need a protocol implementation for ForwardStatMessage using Version 19 and higher */
1326
1327 /* sendLineStatResponse Message */
1328 /*!
1329 * \brief Send Start Line State Response Message (V3)
1330 */
sccp_protocol_sendLineStatRespV3(constDevicePtr d,uint32_t lineNumber,char * dirNumber,char * fullyQualifiedDisplayName,char * displayName)1331 static void sccp_protocol_sendLineStatRespV3(constDevicePtr d, uint32_t lineNumber, char *dirNumber, char *fullyQualifiedDisplayName, char *displayName)
1332 {
1333 sccp_msg_t *msg = NULL;
1334 REQ(msg, LineStatMessage);
1335 msg->data.LineStatMessage.lel_lineNumber = htolel(lineNumber);
1336 d->copyStr2Locale(d, msg->data.LineStatMessage.lineDirNumber, dirNumber, sizeof(msg->data.LineStatMessage.lineDirNumber));
1337 d->copyStr2Locale(d, msg->data.LineStatMessage.lineFullyQualifiedDisplayName, fullyQualifiedDisplayName, sizeof(msg->data.LineStatMessage.lineFullyQualifiedDisplayName));
1338 d->copyStr2Locale(d, msg->data.LineStatMessage.lineDisplayName, displayName, sizeof(msg->data.LineStatMessage.lineDisplayName));
1339
1340 //Bit-field: 1-Original Dialed 2-Redirected Dialed, 4-Calling line ID, 8-Calling name ID
1341 //msg->data.LineStatMessage.lel_lineDisplayOptions = 0x01 & 0x08;
1342 msg->data.LineStatMessage.lel_lineDisplayOptions = htolel(15); // value : 0 or 15
1343 sccp_dev_send(d, msg);
1344 }
1345
1346 /*!
1347 * \brief Send Start Line State Response Message (V17)
1348 */
sccp_protocol_sendLineStatRespV17(constDevicePtr d,uint32_t lineNumber,char * dirNumber,char * fullyQualifiedDisplayName,char * displayName)1349 static void sccp_protocol_sendLineStatRespV17(constDevicePtr d, uint32_t lineNumber, char *dirNumber, char *fullyQualifiedDisplayName, char *displayName)
1350 {
1351 int dirNumLen = dirNumber ? sccp_strlen(dirNumber): 0;
1352 int fqdnLen = fullyQualifiedDisplayName ? sccp_strlen(fullyQualifiedDisplayName): 0;
1353 int displayNameLen = displayName ? sccp_strlen(displayName): 0;
1354 int dummyLen = dirNumLen + fqdnLen + displayNameLen;
1355
1356 int pktLen = SCCP_PACKET_HEADER + dummyLen;
1357 sccp_msg_t *msg = sccp_build_packet(LineStatDynamicMessage, pktLen);
1358 msg->data.LineStatDynamicMessage.lel_lineNumber = htolel(lineNumber);
1359
1360 if (dummyLen) {
1361 char *dummyPtr = msg->data.LineStatDynamicMessage.dummy;
1362 d->copyStr2Locale(d, dummyPtr, dirNumber, dirNumLen+1);
1363 dummyPtr += dirNumLen + 1;
1364 d->copyStr2Locale(d, dummyPtr, fullyQualifiedDisplayName, fqdnLen+1);
1365 dummyPtr += fqdnLen + 1;
1366 d->copyStr2Locale(d, dummyPtr, displayName, displayNameLen+1);
1367 dummyPtr += displayNameLen + 1;
1368 }
1369
1370 //Bit-field: 1-Original Dialed 2-Redirected Dialed, 4-Calling line ID, 8-Calling name ID
1371 //int lineDisplayOptions = 0x01 & 0x08;
1372 //int lineDisplayOptions = htolel(15);
1373 //msg->data.LineStatDynamicMessage.lel_lineDisplayOptions = htolel(lineDisplayOptions);
1374 sccp_dev_send(d, msg);
1375 }
1376
1377 /*
1378 static void sccp_protocol_sendLineStatRespV17(constDevicePtr d, uint32_t lineNumber, char *dirNumber, char *fullyQualifiedDisplayName, char *displayName)
1379 {
1380 sccp_msg_t *msg = NULL;
1381 REQ(msg, LineStatDynamicMessage);
1382 msg->data.LineStatDynamicMessage.lel_lineNumber = htolel(lineNumber);
1383 d->copyStr2Locale(d, msg->data.LineStatDynamicMessage.lineDirNumber, dirNumber, sizeof(msg->data.LineStatDynamicMessage.lineDirNumber));
1384 d->copyStr2Locale(d, msg->data.LineStatDynamicMessage.lineFullyQualifiedDisplayName, fullyQualifiedDisplayName, sizeof(msg->data.LineStatDynamicMessage.lineFullyQualifiedDisplayName));
1385 d->copyStr2Locale(d, msg->data.LineStatDynamicMessage.lineTextLabel, displayName, sizeof(msg->data.LineStatDynamicMessage.lineTextLabel));
1386
1387 //Bit-field: 1-Original Dialed 2-Redirected Dialed, 4-Calling line ID, 8-Calling name ID
1388 //msg->data.LineStatDynamicMessage.lel_lineDisplayOptions = 0x01 & 0x08;
1389 msg->data.LineStatDynamicMessage.lel_lineDisplayOptions = htolel(15);
1390 sccp_dev_send(d, msg);
1391 }
1392 */
1393 /* done - sendLineStat */
1394
1395 /* =================================================================================================================== Parse Received Messages */
1396
1397 /*!
1398 * \brief OpenReceiveChannelAck
1399 */
sccp_protocol_parseOpenReceiveChannelAckV3(constMessagePtr msg,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss,uint32_t * passthrupartyid,uint32_t * callReference)1400 static void sccp_protocol_parseOpenReceiveChannelAckV3(constMessagePtr msg, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss, uint32_t * passthrupartyid, uint32_t * callReference)
1401 {
1402 *mediastatus = letohl(msg->data.OpenReceiveChannelAck.v3.lel_mediastatus);
1403 *callReference = letohl(msg->data.OpenReceiveChannelAck.v3.lel_callReference);
1404 *passthrupartyid = letohl(msg->data.OpenReceiveChannelAck.v3.lel_passThruPartyId);
1405
1406 ss->ss_family = AF_INET;
1407 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1408
1409 memcpy(&sin->sin_addr, &msg->data.OpenReceiveChannelAck.v3.bel_ipAddr, sizeof(sin->sin_addr));
1410 sin->sin_port = htons(htolel(msg->data.OpenReceiveChannelAck.v3.lel_portNumber));
1411 }
1412
sccp_protocol_parseOpenReceiveChannelAckV17(constMessagePtr msg,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss,uint32_t * passthrupartyid,uint32_t * callReference)1413 static void sccp_protocol_parseOpenReceiveChannelAckV17(constMessagePtr msg, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss, uint32_t * passthrupartyid, uint32_t * callReference)
1414 {
1415 *mediastatus = letohl(msg->data.OpenReceiveChannelAck.v17.lel_mediastatus);
1416 *callReference = letohl(msg->data.OpenReceiveChannelAck.v17.lel_callReference);
1417 *passthrupartyid = letohl(msg->data.OpenReceiveChannelAck.v17.lel_passThruPartyId);
1418
1419 if (letohl(msg->data.OpenReceiveChannelAck.v17.lel_ipv46) == 0) { // read ipv4 address
1420 ss->ss_family = AF_INET;
1421 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1422
1423 memcpy(&sin->sin_addr, &msg->data.OpenReceiveChannelAck.v17.bel_ipAddr, sizeof(sin->sin_addr));
1424 sin->sin_port = htons(htolel(msg->data.OpenReceiveChannelAck.v17.lel_portNumber));
1425 } else { // read ipv6 address
1426 /* what to do with IPv4-mapped IPv6 addresses */
1427 ss->ss_family = AF_INET6;
1428 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
1429
1430 memcpy(&sin6->sin6_addr, &msg->data.OpenReceiveChannelAck.v17.bel_ipAddr, sizeof(sin6->sin6_addr));
1431 sin6->sin6_port = htons(htolel(msg->data.OpenReceiveChannelAck.v17.lel_portNumber));
1432 }
1433 }
1434
sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3(constMessagePtr msg,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss,uint32_t * passthrupartyid,uint32_t * callReference)1435 static void sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3(constMessagePtr msg, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss, uint32_t * passthrupartyid, uint32_t * callReference)
1436 {
1437 *mediastatus = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v3.lel_mediastatus);
1438 *passthrupartyid = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v3.lel_passThruPartyId);
1439 *callReference = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v3.lel_callReference);
1440
1441 ss->ss_family = AF_INET;
1442 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1443
1444 memcpy(&sin->sin_addr, &msg->data.OpenMultiMediaReceiveChannelAckMessage.v3.bel_ipAddr, sizeof(sin->sin_addr));
1445 sin->sin_port = htons(htolel(msg->data.OpenMultiMediaReceiveChannelAckMessage.v3.lel_portNumber));
1446 }
1447
sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17(constMessagePtr msg,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss,uint32_t * passthrupartyid,uint32_t * callReference)1448 static void sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17(constMessagePtr msg, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss, uint32_t * passthrupartyid, uint32_t * callReference)
1449 {
1450 *mediastatus = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_mediastatus);
1451 *passthrupartyid = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_passThruPartyId);
1452 *callReference = letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_callReference);
1453
1454 if (letohl(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_ipv46) == 0) { // read ipv4 address
1455 ss->ss_family = AF_INET;
1456 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1457
1458 memcpy(&sin->sin_addr, &msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.bel_ipAddr, sizeof(sin->sin_addr));
1459 sin->sin_port = htons(htolel(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_portNumber));
1460 } else { // read ipv6 address
1461 /* what to do with IPv4-mapped IPv6 addresses */
1462 ss->ss_family = AF_INET6;
1463 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
1464
1465 memcpy(&sin6->sin6_addr, &msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.bel_ipAddr, sizeof(sin6->sin6_addr));
1466 sin6->sin6_port = htons(htolel(msg->data.OpenMultiMediaReceiveChannelAckMessage.v17.lel_portNumber));
1467 }
1468 }
1469
1470 /*!
1471 * \brief StartMediaTransmissionAck
1472 */
sccp_protocol_parseStartMediaTransmissionAckV3(constMessagePtr msg,uint32_t * partyID,uint32_t * callID,uint32_t * callID1,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss)1473 static void sccp_protocol_parseStartMediaTransmissionAckV3(constMessagePtr msg, uint32_t * partyID, uint32_t * callID, uint32_t * callID1, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss)
1474 {
1475 *partyID = letohl(msg->data.StartMediaTransmissionAck.v3.lel_passThruPartyId);
1476 *callID = letohl(msg->data.StartMediaTransmissionAck.v3.lel_callReference);
1477 *callID1 = letohl(msg->data.StartMediaTransmissionAck.v3.lel_callReference1);
1478 *mediastatus = letohl(msg->data.StartMediaTransmissionAck.v3.lel_mediastatus);
1479
1480 ss->ss_family = AF_INET;
1481 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1482
1483 memcpy(&sin->sin_addr, &msg->data.StartMediaTransmissionAck.v3.bel_ipAddr, sizeof(sin->sin_addr));
1484 sin->sin_port = htons(htolel(msg->data.StartMediaTransmissionAck.v3.lel_portNumber));
1485 }
1486
sccp_protocol_parseStartMediaTransmissionAckV17(constMessagePtr msg,uint32_t * partyID,uint32_t * callID,uint32_t * callID1,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss)1487 static void sccp_protocol_parseStartMediaTransmissionAckV17(constMessagePtr msg, uint32_t * partyID, uint32_t * callID, uint32_t * callID1, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss)
1488 {
1489 *partyID = letohl(msg->data.StartMediaTransmissionAck.v17.lel_passThruPartyId);
1490 *callID = letohl(msg->data.StartMediaTransmissionAck.v17.lel_callReference);
1491 *callID1 = letohl(msg->data.StartMediaTransmissionAck.v17.lel_callReference1);
1492 *mediastatus = letohl(msg->data.StartMediaTransmissionAck.v17.lel_mediastatus);
1493
1494 if (letohl(msg->data.StartMediaTransmissionAck.v17.lel_ipv46) == 0) { // read ipv4 address
1495 ss->ss_family = AF_INET;
1496 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1497
1498 memcpy(&sin->sin_addr, &msg->data.StartMediaTransmissionAck.v17.bel_ipAddr, sizeof(sin->sin_addr));
1499 sin->sin_port = htons(htolel(msg->data.StartMediaTransmissionAck.v17.lel_portNumber));
1500 } else { // read ipv6 address
1501 /* what to do with IPv4-mapped IPv6 addresses */
1502 ss->ss_family = AF_INET6;
1503 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
1504
1505 memcpy(&sin6->sin6_addr, &msg->data.StartMediaTransmissionAck.v17.bel_ipAddr, sizeof(sin6->sin6_addr));
1506 sin6->sin6_port = htons(htolel(msg->data.StartMediaTransmissionAck.v17.lel_portNumber));
1507 }
1508 }
1509
1510 /*!
1511 * \brief StartMultiMediaTransmissionAck
1512 */
sccp_protocol_parseStartMultiMediaTransmissionAckV3(constMessagePtr msg,uint32_t * partyID,uint32_t * callID,uint32_t * callID1,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss)1513 static void sccp_protocol_parseStartMultiMediaTransmissionAckV3(constMessagePtr msg, uint32_t * partyID, uint32_t * callID, uint32_t * callID1, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss)
1514 {
1515 *partyID = letohl(msg->data.StartMultiMediaTransmissionAck.v3.lel_passThruPartyId);
1516 *callID = letohl(msg->data.StartMultiMediaTransmissionAck.v3.lel_callReference);
1517 *callID1 = letohl(msg->data.StartMultiMediaTransmissionAck.v3.lel_callReference1);
1518 *mediastatus = letohl(msg->data.StartMultiMediaTransmissionAck.v3.lel_mediastatus);
1519
1520 ss->ss_family = AF_INET;
1521 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1522
1523 memcpy(&sin->sin_addr, &msg->data.StartMultiMediaTransmissionAck.v3.bel_ipAddr, sizeof(sin->sin_addr));
1524 sin->sin_port = htons(htolel(msg->data.StartMultiMediaTransmissionAck.v3.lel_portNumber));
1525 }
1526
sccp_protocol_parseStartMultiMediaTransmissionAckV17(constMessagePtr msg,uint32_t * partyID,uint32_t * callID,uint32_t * callID1,skinny_mediastatus_t * mediastatus,struct sockaddr_storage * ss)1527 static void sccp_protocol_parseStartMultiMediaTransmissionAckV17(constMessagePtr msg, uint32_t * partyID, uint32_t * callID, uint32_t * callID1, skinny_mediastatus_t * mediastatus, struct sockaddr_storage *ss)
1528 {
1529 *partyID = letohl(msg->data.StartMultiMediaTransmissionAck.v17.lel_passThruPartyId);
1530 *callID = letohl(msg->data.StartMultiMediaTransmissionAck.v17.lel_callReference);
1531 *callID1 = letohl(msg->data.StartMultiMediaTransmissionAck.v17.lel_callReference1);
1532 *mediastatus = letohl(msg->data.StartMultiMediaTransmissionAck.v17.lel_mediastatus);
1533
1534 if (letohl(msg->data.StartMultiMediaTransmissionAck.v17.lel_ipv46) == 0) { // read ipv4 address
1535 ss->ss_family = AF_INET;
1536 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1537
1538 memcpy(&sin->sin_addr, &msg->data.StartMultiMediaTransmissionAck.v17.bel_ipAddr, sizeof(struct in_addr));
1539 sin->sin_port = htons(htolel(msg->data.StartMultiMediaTransmissionAck.v17.lel_portNumber));
1540 } else { // read ipv6 address
1541 /* what to do with IPv4-mapped IPv6 addresses */
1542 ss->ss_family = AF_INET6;
1543 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
1544
1545 memcpy(&sin6->sin6_addr, &msg->data.StartMultiMediaTransmissionAck.v17.bel_ipAddr, sizeof(sin6->sin6_addr));
1546 sin6->sin6_port = htons(htolel(msg->data.StartMultiMediaTransmissionAck.v17.lel_portNumber));
1547 }
1548 }
1549
1550 /*!
1551 * \brief EnblocCallMessage
1552 */
sccp_protocol_parseEnblocCallV3(constMessagePtr msg,char * calledParty,uint32_t * lineInstance)1553 static void sccp_protocol_parseEnblocCallV3(constMessagePtr msg, char *calledParty, uint32_t * lineInstance)
1554 {
1555 sccp_copy_string(calledParty, msg->data.EnblocCallMessage.v3.calledParty, StationMaxDirnumSize);
1556 *lineInstance = 0; // v3 - v16 don't provicde lineInstance during enbloc dialing
1557 }
1558
sccp_protocol_parseEnblocCallV17(constMessagePtr msg,char * calledParty,uint32_t * lineInstance)1559 static void sccp_protocol_parseEnblocCallV17(constMessagePtr msg, char *calledParty, uint32_t * lineInstance)
1560 {
1561 sccp_copy_string(calledParty, msg->data.EnblocCallMessage.v17.calledParty, StationMaxDirnumSize);
1562 *lineInstance = letohl(msg->data.EnblocCallMessage.v17.lel_lineInstance);
1563 }
1564
sccp_protocol_parseEnblocCallV22(constMessagePtr msg,char * calledParty,uint32_t * lineInstance)1565 static void sccp_protocol_parseEnblocCallV22(constMessagePtr msg, char *calledParty, uint32_t * lineInstance)
1566 {
1567 sccp_copy_string(calledParty, msg->data.EnblocCallMessage.v18u.calledParty, 25);
1568
1569 /* message exists in both packed and unpacked version */
1570 /* 8945 v22 unpacked */
1571 // 00000000 - 24 00 00 00 16 00 00 00 04 00 00 00 39 38 30 31 - $...........9801
1572 // 00000010 - 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 1...............
1573 // 00000020 - 00 00 00 00 00 00 00 00 01 00 00 00 - ............
1574
1575 /* 7970 v22 packed*/
1576 // 00000000 - 24 00 00 00 16 00 00 00 04 00 00 00 39 38 30 31 - $...........9801
1577 // 00000010 - 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 1...............
1578 // 00000020 - 00 00 00 00 00 01 00 00 00 00 00 00 - ............
1579
1580 if (letohl(msg->data.EnblocCallMessage.v18u.lel_lineInstance) > 0) {
1581 *lineInstance = letohl(msg->data.EnblocCallMessage.v18u.lel_lineInstance);
1582 } else {
1583 #if defined(HAVE_UNALIGNED_BUSERROR)
1584 *lineInstance = letohl(get_unaligned_uint32((const void *) &msg->data.EnblocCallMessage.v18p.lel_lineInstance));
1585 #else
1586 *lineInstance = letohl(msg->data.EnblocCallMessage.v18p.lel_lineInstance);
1587 #endif
1588 }
1589 }
1590
1591 /* sendPortResponse */
sccp_protocol_parsePortResponseV3(constMessagePtr msg,uint32_t * conferenceId,uint32_t * callReference,uint32_t * passThruPartyId,struct sockaddr_storage * ss,uint32_t * RTCPPortNumber,skinny_mediaType_t * mediaType)1592 static void sccp_protocol_parsePortResponseV3(constMessagePtr msg, uint32_t *conferenceId, uint32_t *callReference, uint32_t *passThruPartyId, struct sockaddr_storage *ss, uint32_t * RTCPPortNumber, skinny_mediaType_t *mediaType)
1593 {
1594 *conferenceId = letohl(msg->data.PortResponseMessage.v3.lel_conferenceId);
1595 *callReference = letohl(msg->data.PortResponseMessage.v3.lel_callReference);
1596 *passThruPartyId = letohl(msg->data.PortResponseMessage.v3.lel_passThruPartyId);
1597
1598 ss->ss_family = AF_INET;
1599 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1600 memcpy(&sin->sin_addr, &msg->data.PortResponseMessage.v3.bel_ipAddr, sizeof(sin->sin_addr));
1601 sin->sin_port = htons(htolel(msg->data.PortResponseMessage.v3.lel_portNumber));
1602
1603 *RTCPPortNumber = letohl(msg->data.PortResponseMessage.v3.lel_RTCPPortNumber);
1604 *mediaType = SKINNY_MEDIATYPE_SENTINEL;
1605 }
1606
sccp_protocol_parsePortResponseV19(constMessagePtr msg,uint32_t * conferenceId,uint32_t * callReference,uint32_t * passThruPartyId,struct sockaddr_storage * ss,uint32_t * RTCPPortNumber,skinny_mediaType_t * mediaType)1607 static void sccp_protocol_parsePortResponseV19(constMessagePtr msg, uint32_t *conferenceId, uint32_t *callReference, uint32_t *passThruPartyId, struct sockaddr_storage *ss, uint32_t * RTCPPortNumber, skinny_mediaType_t *mediaType)
1608 {
1609 *conferenceId = letohl(msg->data.PortResponseMessage.v19.lel_conferenceId);
1610 *callReference = letohl(msg->data.PortResponseMessage.v19.lel_callReference);
1611 *passThruPartyId = letohl(msg->data.PortResponseMessage.v19.lel_passThruPartyId);
1612
1613 if (letohl(msg->data.PortResponseMessage.v19.lel_ipv46) == 0) { // read ipv4 address
1614 ss->ss_family = AF_INET;
1615 struct sockaddr_in *sin = (struct sockaddr_in *) ss;
1616
1617 memcpy(&sin->sin_addr, &msg->data.PortResponseMessage.v19.bel_ipAddr, sizeof(sin->sin_addr));
1618 sin->sin_port = htons(htolel(msg->data.PortResponseMessage.v19.lel_portNumber));
1619 } else { // read ipv6 address
1620 ss->ss_family = AF_INET6;
1621 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
1622
1623 memcpy(&sin6->sin6_addr, &msg->data.PortResponseMessage.v19.bel_ipAddr, sizeof(sin6->sin6_addr));
1624 sin6->sin6_port = htons(htolel(msg->data.PortResponseMessage.v19.lel_portNumber));
1625 }
1626 *RTCPPortNumber = letohl(msg->data.PortResponseMessage.v19.lel_RTCPPortNumber);
1627 *mediaType = letohl(msg->data.PortResponseMessage.v19.lel_mediaType);
1628 }
1629 /* done - sendPortResponse */
1630
1631 /* =================================================================================================================== Map Messages to Protocol Version */
1632
1633 /*!
1634 * \brief SCCP Protocol Version to Message Mapping
1635 */
1636 static const sccp_deviceProtocol_t *sccpProtocolDefinition[] = {
1637 NULL,
1638 NULL,
1639 NULL,
1640 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 3, TimeDateReqMessage, sccp_protocol_sendCallInfoV3, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV3, sccp_protocol_sendStaticDisplayprompt, sccp_protocol_sendStaticDisplayNotify, sccp_protocol_sendStaticDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1641 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1642 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3}, /* default impl */
1643 NULL,
1644 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 5, TimeDateReqMessage, sccp_protocol_sendCallInfoV3, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendStaticDisplayprompt, sccp_protocol_sendStaticDisplayNotify, sccp_protocol_sendStaticDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1645 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1646 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1647 NULL,
1648 NULL,
1649 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 8, TimeDateReqMessage, sccp_protocol_sendCallInfoV7, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1650 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1651 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1652 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 9, TimeDateReqMessage, sccp_protocol_sendCallInfoV7, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1653 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1654 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1655 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 10, TimeDateReqMessage, sccp_protocol_sendCallInfoV7, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1656 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1657 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1658 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 11, TimeDateReqMessage, sccp_protocol_sendCallInfoV7, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV3,
1659 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1660 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1661 NULL,
1662 NULL,
1663 NULL,
1664 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 15, TimeDateReqMessage, sccp_protocol_sendCallInfoV7, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV12,
1665 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1666 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1667 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 16, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3, sccp_protocol_sendOpenMultiMediaChannelV12,
1668 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1669 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1670 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 17, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV17, sccp_protocol_sendOpenMultiMediaChannelV17,
1671 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV17, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1672 sccp_protocol_parseOpenReceiveChannelAckV17, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17, sccp_protocol_parseStartMediaTransmissionAckV17, sccp_protocol_parseStartMultiMediaTransmissionAckV17, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV3},
1673 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 18, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV18, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatusV18, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV17, sccp_protocol_sendOpenMultiMediaChannelV17,
1674 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV17, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1675 sccp_protocol_parseOpenReceiveChannelAckV17, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17, sccp_protocol_parseStartMediaTransmissionAckV17, sccp_protocol_parseStartMultiMediaTransmissionAckV17, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV3},
1676 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 19, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV18, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatusV18, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV17,
1677 sccp_protocol_sendOpenMultiMediaChannelV17,
1678 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV17, sccp_protocol_sendConnectionStatisticsReqV19, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1679 sccp_protocol_parseOpenReceiveChannelAckV17, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17, sccp_protocol_parseStartMediaTransmissionAckV17, sccp_protocol_parseStartMultiMediaTransmissionAckV17, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV19},
1680 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 20, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV18, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatusV18, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV17,
1681 sccp_protocol_sendOpenMultiMediaChannelV17,
1682 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV17, sccp_protocol_sendConnectionStatisticsReqV19, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1683 sccp_protocol_parseOpenReceiveChannelAckV17, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17, sccp_protocol_parseStartMediaTransmissionAckV17, sccp_protocol_parseStartMultiMediaTransmissionAckV17, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV19},
1684 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 21, TimeDateReqMessage, sccp_protocol_sendCallInfoV16, sccp_protocol_sendDialedNumberV18, sccp_protocol_sendRegisterAckV11, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatusV18, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV17,
1685 sccp_protocol_sendOpenMultiMediaChannelV17,
1686 sccp_protocol_sendStartMultiMediaTransmissionV17, sccp_protocol_sendStartMediaTransmissionV17, sccp_protocol_sendConnectionStatisticsReqV19, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1687 sccp_protocol_parseOpenReceiveChannelAckV17, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17, sccp_protocol_parseStartMediaTransmissionAckV17, sccp_protocol_parseStartMultiMediaTransmissionAckV17, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV19},
1688 &(sccp_deviceProtocol_t) {SCCP_PROTOCOL, 22, TimeDateReqMessage, sccp_protocol_sendCallInfoV16,sccp_protocol_sendDialedNumberV18,sccp_protocol_sendRegisterAckV11,sccp_protocol_sendDynamicDisplayprompt,sccp_protocol_sendDynamicDisplayNotify,sccp_protocol_sendDynamicDisplayPriNotify,sccp_protocol_sendCallForwardStatusV18,sccp_protocol_sendUserToDeviceDataVersion1Message,sccp_protocol_sendMultiMediaCommand,sccp_protocol_sendOpenReceiveChannelv22,
1689 sccp_protocol_sendOpenMultiMediaChannelV17,
1690 sccp_protocol_sendStartMultiMediaTransmissionV17,sccp_protocol_sendStartMediaTransmissionv22,sccp_protocol_sendConnectionStatisticsReqV19, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV17,
1691 sccp_protocol_parseOpenReceiveChannelAckV17,sccp_protocol_parseOpenMultiMediaReceiveChannelAckV17,sccp_protocol_parseStartMediaTransmissionAckV17,sccp_protocol_parseStartMultiMediaTransmissionAckV17,sccp_protocol_parseEnblocCallV22, sccp_protocol_parsePortResponseV19},
1692 };
1693
1694 /*!
1695 * \brief SPCP Protocol Version to Message Mapping
1696 */
1697 static const sccp_deviceProtocol_t *spcpProtocolDefinition[] = {
1698 &(sccp_deviceProtocol_t) {SPCP_PROTOCOL, 0, RegisterAvailableLinesMessage, sccp_protocol_sendCallInfoV3, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3,
1699 sccp_protocol_sendOpenMultiMediaChannelV3,
1700 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV3, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1701 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV3, sccp_protocol_parsePortResponseV3},
1702 NULL,
1703 NULL,
1704 NULL,
1705 NULL,
1706 NULL,
1707 NULL,
1708 NULL,
1709 &(sccp_deviceProtocol_t) {SPCP_PROTOCOL, 8, RegisterAvailableLinesMessage, sccp_protocol_sendCallInfoV3, sccp_protocol_sendDialedNumberV3, sccp_protocol_sendRegisterAckV4, sccp_protocol_sendDynamicDisplayprompt, sccp_protocol_sendDynamicDisplayNotify, sccp_protocol_sendDynamicDisplayPriNotify, sccp_protocol_sendCallForwardStatus, sccp_protocol_sendUserToDeviceDataVersion1Message, sccp_protocol_sendMultiMediaCommand, sccp_protocol_sendOpenReceiveChannelV3,
1710 sccp_protocol_sendOpenMultiMediaChannelV3,
1711 sccp_protocol_sendStartMultiMediaTransmissionV3, sccp_protocol_sendStartMediaTransmissionV3, sccp_protocol_sendConnectionStatisticsReqV19, sccp_protocol_sendPortRequest,sccp_protocol_sendPortClose, sccp_protocol_sendLineStatRespV3,
1712 sccp_protocol_parseOpenReceiveChannelAckV3, sccp_protocol_parseOpenMultiMediaReceiveChannelAckV3, sccp_protocol_parseStartMediaTransmissionAckV3, sccp_protocol_parseStartMultiMediaTransmissionAckV3, sccp_protocol_parseEnblocCallV17, sccp_protocol_parsePortResponseV19},
1713 };
1714
1715 /*!
1716 * \brief Get Maximum Supported Version Number by Protocol Type
1717 */
sccp_protocol_getMaxSupportedVersionNumber(int type)1718 uint8_t __CONST__ sccp_protocol_getMaxSupportedVersionNumber(int type)
1719 {
1720 switch (type) {
1721 case SCCP_PROTOCOL:
1722 return ARRAY_LEN(sccpProtocolDefinition) - 1;
1723 case SPCP_PROTOCOL:
1724 return ARRAY_LEN(spcpProtocolDefinition) - 1;
1725 default:
1726 return 0;
1727 }
1728 }
1729
sccp_protocol_isProtocolSupported(uint8_t type,uint8_t version)1730 gcc_inline boolean_t sccp_protocol_isProtocolSupported(uint8_t type, uint8_t version)
1731 {
1732 const sccp_deviceProtocol_t **protocolDef = NULL;
1733 size_t protocolArraySize = 0 ;
1734
1735 switch (type) {
1736 case SCCP_PROTOCOL:
1737 protocolArraySize = ARRAY_LEN(sccpProtocolDefinition);
1738 protocolDef = sccpProtocolDefinition;
1739 break;
1740 case SPCP_PROTOCOL:
1741 protocolArraySize = ARRAY_LEN(spcpProtocolDefinition);
1742 protocolDef = spcpProtocolDefinition;
1743 break;
1744 default:
1745 pbx_log(LOG_WARNING, "SCCP: Unknown Protocol\n");
1746 }
1747
1748 return (version < protocolArraySize && protocolDef[version] != NULL) ? TRUE : FALSE;
1749 }
1750
1751 /*!
1752 * \brief Get Maximum Possible Protocol Supported by Device
1753 */
sccp_protocol_getDeviceProtocol(constDevicePtr device,int type)1754 const sccp_deviceProtocol_t *sccp_protocol_getDeviceProtocol(constDevicePtr device, int type)
1755 {
1756 uint8_t version = device->protocolversion;
1757 const sccp_deviceProtocol_t ** protocolDef = NULL;
1758 size_t protocolArraySize = 0;
1759 uint8_t returnProtocol = 0;
1760
1761 sccp_log(DEBUGCAT_DEVICE) (VERBOSE_PREFIX_3 "SCCP: searching for our capability for device protocol version %d\n", version);
1762
1763 if (type == SCCP_PROTOCOL) {
1764 protocolArraySize = ARRAY_LEN(sccpProtocolDefinition);
1765 protocolDef = sccpProtocolDefinition;
1766 returnProtocol = 3; // setting minimally returned protocol
1767 sccp_log(DEBUGCAT_DEVICE) (VERBOSE_PREFIX_3 "SCCP: searching for our capability for device protocol SCCP\n");
1768 } else {
1769 protocolArraySize = ARRAY_LEN(spcpProtocolDefinition);
1770 protocolDef = spcpProtocolDefinition;
1771 returnProtocol = 0;
1772 sccp_log(DEBUGCAT_DEVICE) (VERBOSE_PREFIX_3 "SCCP: searching for our capability for device protocol SPCP\n");
1773 }
1774
1775 for(uint8_t i = (protocolArraySize - 1); i > 0; i--) {
1776 if (protocolDef[i] != NULL && version >= protocolDef[i]->version) {
1777 sccp_log(DEBUGCAT_DEVICE) (VERBOSE_PREFIX_3 "%s: found protocol version '%d' at %d\n", protocolDef[i]->type == SCCP_PROTOCOL ? "SCCP" : "SPCP", protocolDef[i]->version, i);
1778 returnProtocol = i;
1779 break;
1780 }
1781 }
1782
1783 return protocolDef[returnProtocol];
1784 }
1785
skinny_keymode2longstr(skinny_keymode_t keymode)1786 const char * const __CONST__ skinny_keymode2longstr(skinny_keymode_t keymode)
1787 {
1788 switch (keymode) {
1789 case KEYMODE_ONHOOK:
1790 return "On Hook";
1791 case KEYMODE_CONNECTED:
1792 return "Connected";
1793 case KEYMODE_ONHOLD:
1794 return "On Hold";
1795 case KEYMODE_RINGIN:
1796 return "Incoming Call Ringing";
1797 case KEYMODE_OFFHOOK:
1798 return "Off Hook";
1799 case KEYMODE_CONNTRANS:
1800 return "Connect with Transferable Call";
1801 case KEYMODE_DIGITSFOLL:
1802 return "More Digits Following";
1803 case KEYMODE_CONNCONF:
1804 return "Connected to Conference";
1805 case KEYMODE_RINGOUT:
1806 return "Outgoing Call Ringing";
1807 case KEYMODE_OFFHOOKFEAT:
1808 return "Off Hook with Features";
1809 case KEYMODE_INUSEHINT:
1810 return "Hint is in use";
1811 case KEYMODE_ONHOOKSTEALABLE:
1812 return "On Hook with Stealable Call Present";
1813 case KEYMODE_HOLDCONF:
1814 return "Have a Conference On Hold";
1815 default:
1816 return "Unknown KeyMode";
1817 }
1818 }
1819
1820 const struct messageinfo sccp_messageinfo[] = {
1821 /* clang-format off */
1822 /* DEV -> PBX */
1823 [KeepAliveMessage] = { KeepAliveMessage, "Keep Alive Message", offsize(sccp_data_t, StationKeepAliveMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1824 [RegisterMessage] = { RegisterMessage, "Register Message", offsize(sccp_data_t, RegisterMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1825 [IpPortMessage] = { IpPortMessage, "Ip-Port Message", offsize(sccp_data_t, IpPortMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1826 [KeypadButtonMessage] = { KeypadButtonMessage, "Keypad Button Message", offsize(sccp_data_t, KeypadButtonMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1827 /**/[EnblocCallMessage] = { EnblocCallMessage, "Enbloc Call Message", offsize(sccp_data_t, EnblocCallMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1828 [StimulusMessage] = { StimulusMessage, "Stimulus Message", offsize(sccp_data_t, StimulusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1829 [OffHookMessage] = { OffHookMessage, "Off-Hook Message", offsize(sccp_data_t, OffHookMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1830 [OnHookMessage] = { OnHookMessage, "On-Hook Message", offsize(sccp_data_t, OnHookMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1831 [HookFlashMessage] = { HookFlashMessage, "Hook-Flash Message", offsize(sccp_data_t, HookFlashMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1832 [ForwardStatReqMessage] = { ForwardStatReqMessage, "Forward State Request", offsize(sccp_data_t, ForwardStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1833 [SpeedDialStatReqMessage] = { SpeedDialStatReqMessage, "Speed-Dial State Request", offsize(sccp_data_t, SpeedDialStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1834 [LineStatReqMessage] = { LineStatReqMessage, "Line State Request", offsize(sccp_data_t, LineStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1835 [ConfigStatReqMessage] = { ConfigStatReqMessage, "Config State Request", offsize(sccp_data_t, ConfigStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1836 /**/[TimeDateReqMessage] = { TimeDateReqMessage, "Time Date Request", offsize(sccp_data_t, TimeDateReqMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1837 [ButtonTemplateReqMessage] = { ButtonTemplateReqMessage, "Button Template Request", offsize(sccp_data_t, ButtonTemplateReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1838 [VersionReqMessage] = { VersionReqMessage, "Version Request", offsize(sccp_data_t, VersionReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1839 [CapabilitiesResMessage] = { CapabilitiesResMessage, "Capabilities Response Message", offsize(sccp_data_t, CapabilitiesResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1840 [MediaPortListMessage] = { MediaPortListMessage, "Media Port List Message", offsize(sccp_data_t, MediaPortListMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1841 [ServerReqMessage] = { ServerReqMessage, "Server Request", offsize(sccp_data_t, ServerReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1842 [AlarmMessage] = { AlarmMessage, "Alarm Message", offsize(sccp_data_t, AlarmMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1843 [MulticastMediaReceptionAck] = { MulticastMediaReceptionAck, "Multicast Media Reception Acknowledge", offsize(sccp_data_t, MulticastMediaReceptionAck), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1844 [OpenReceiveChannelAck] = { OpenReceiveChannelAck, "Open Receive Channel Acknowledge", offsize(sccp_data_t, OpenReceiveChannelAck), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1845 /*[ConnectionStatisticsRes] = { ConnectionStatisticsRes, "Connection Statistics Response", offsize(sccp_data_t, ConnectionStatisticsRes), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },*/
1846 [ConnectionStatisticsRes] = { ConnectionStatisticsRes, "Connection Statistics Response", offsize(sccp_data_t, ConnectionStatisticsRes), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1847 [OffHookMessageWithCallingPartyMessage] = { OffHookMessageWithCallingPartyMessage, "Off-Hook With Cgpn Message", offsize(sccp_data_t, OffHookMessageWithCallingPartyMessage), SKINNY_MSGTYPE_EVENT,
1848 SKINNY_MSGDIRECTION_DEV2PBX },
1849 [SoftKeySetReqMessage] = { SoftKeySetReqMessage, "SoftKey Set Request", offsize(sccp_data_t, SoftKeySetReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1850 [SoftKeyEventMessage] = { SoftKeyEventMessage, "SoftKey Event Message", offsize(sccp_data_t, SoftKeyEventMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1851 [UnregisterMessage] = { UnregisterMessage, "Unregister Message", offsize(sccp_data_t, UnregisterMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1852 [SoftKeyTemplateReqMessage] = { SoftKeyTemplateReqMessage, "SoftKey Template Request", offsize(sccp_data_t, SoftKeyTemplateReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1853 [RegisterTokenRequest] = { RegisterTokenRequest, "Register Token Request", offsize(sccp_data_t, RegisterTokenRequest), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1854 /**/[MediaTransmissionFailure] = { MediaTransmissionFailure, "Media Transmission Failure", offsize(sccp_data_t, MediaTransmissionFailure), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1855 [HeadsetStatusMessage] = { HeadsetStatusMessage, "Headset Status Message", offsize(sccp_data_t, HeadsetStatusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1856 [MediaResourceNotification] = { MediaResourceNotification, "Media Resource Notification", offsize(sccp_data_t, MediaResourceNotification), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1857 [RegisterAvailableLinesMessage] = { RegisterAvailableLinesMessage, "Register Available Lines Message", offsize(sccp_data_t, RegisterAvailableLinesMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1858 [DeviceToUserDataMessage] = { DeviceToUserDataMessage, "Device To User Data Message", offsize(sccp_data_t, DeviceToUserDataMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1859 [DeviceToUserDataResponseMessage] = { DeviceToUserDataResponseMessage, "Device To User Data Response", offsize(sccp_data_t, DeviceToUserDataResponseMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1860 [UpdateCapabilitiesMessage] = { UpdateCapabilitiesMessage, "Update Capabilities Message", offsize(sccp_data_t, UpdateCapabilitiesMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1861 [OpenMultiMediaReceiveChannelAckMessage] = { OpenMultiMediaReceiveChannelAckMessage, "Open MultiMedia Receive Channel Acknowledge", offsize(sccp_data_t, OpenMultiMediaReceiveChannelAckMessage),
1862 SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1863 [ClearConferenceMessage] = { ClearConferenceMessage, "Clear Conference Message", offsize(sccp_data_t, ClearConferenceMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1864 [ServiceURLStatReqMessage] = { ServiceURLStatReqMessage, "Service URL State Request", offsize(sccp_data_t, ServiceURLStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1865 [FeatureStatReqMessage] = { FeatureStatReqMessage, "Feature State Request", offsize(sccp_data_t, FeatureStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1866 [CreateConferenceResMessage] = { CreateConferenceResMessage, "Create Conference Response", offsize(sccp_data_t, CreateConferenceResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1867 [DeleteConferenceResMessage] = { DeleteConferenceResMessage, "Delete Conference Response", offsize(sccp_data_t, DeleteConferenceResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1868 [ModifyConferenceResMessage] = { ModifyConferenceResMessage, "Modify Conference Response", offsize(sccp_data_t, ModifyConferenceResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1869 [AddParticipantResMessage] = { AddParticipantResMessage, "Add Participant Response", offsize(sccp_data_t, AddParticipantResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1870 [AuditConferenceResMessage] = { AuditConferenceResMessage, "Audit Conference Response", offsize(sccp_data_t, AuditConferenceResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1871 [AuditParticipantResMessage] = { AuditParticipantResMessage, "Audit Participant Response", offsize(sccp_data_t, AuditParticipantResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1872 [DeviceToUserDataVersion1Message] = { DeviceToUserDataVersion1Message, "Device To User Data Version1 Message", offsize(sccp_data_t, DeviceToUserDataVersion1Message), SKINNY_MSGTYPE_EVENT,
1873 SKINNY_MSGDIRECTION_DEV2PBX },
1874 [DeviceToUserDataResponseVersion1Message] = { DeviceToUserDataResponseVersion1Message, "Device To User Data Version1 Response", offsize(sccp_data_t, DeviceToUserDataResponseVersion1Message), SKINNY_MSGTYPE_EVENT,
1875 SKINNY_MSGDIRECTION_DEV2PBX },
1876 [SubscriptionStatReqMessage] = { SubscriptionStatReqMessage, "Subscription Status Request (DialedPhoneBook)", offsize(sccp_data_t, SubscriptionStatReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
1877 [AccessoryStatusMessage] = { AccessoryStatusMessage, "Accessory Status Message", offsize(sccp_data_t, AccessoryStatusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1878
1879 /* PBX -> DEV */
1880 [RegisterAckMessage] = { RegisterAckMessage, "Register Acknowledge", offsize(sccp_data_t, RegisterAckMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1881 [StartToneMessage] = { StartToneMessage, "Start Tone Message", offsize(sccp_data_t, StartToneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1882 [StopToneMessage] = { StopToneMessage, "Stop Tone Message", offsize(sccp_data_t, StopToneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1883 [SetRingerMessage] = { SetRingerMessage, "Set Ringer Message", offsize(sccp_data_t, SetRingerMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1884 [SetLampMessage] = { SetLampMessage, "Set Lamp Message", offsize(sccp_data_t, SetLampMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1885 [SetHookFlashDetectMessage] = { SetHookFlashDetectMessage, "Set HookFlash Detect Message", offsize(sccp_data_t, SetHookFlashDetectMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1886 [SetSpeakerModeMessage] = { SetSpeakerModeMessage, "Set Speaker Mode Message", offsize(sccp_data_t, SetSpeakerModeMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1887 [SetMicroModeMessage] = { SetMicroModeMessage, "Set Micro Mode Message", offsize(sccp_data_t, SetMicroModeMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1888 /*spa*/[StartMediaTransmission] = { StartMediaTransmission, "Start Media Transmission", offsize(sccp_data_t, StartMediaTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1889 /**/[StopMediaTransmission] = { StopMediaTransmission, "Stop Media Transmission", offsize(sccp_data_t, StopMediaTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1890 /**/[StartMediaReception] = { StartMediaReception, "Start Media Reception", offsize(sccp_data_t, StartMediaReception), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1891 /**/[StopMediaReception] = { StopMediaReception, "Stop Media Reception", offsize(sccp_data_t, StopMediaReception), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1892 [CallInfoMessage] = { CallInfoMessage, "Call Information Message", offsize(sccp_data_t, CallInfoMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1893 [ForwardStatMessage] = { ForwardStatMessage, "Forward State Message", offsize(sccp_data_t, ForwardStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1894 [SpeedDialStatMessage] = { SpeedDialStatMessage, "SpeedDial State Message", offsize(sccp_data_t, SpeedDialStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1895 [LineStatMessage] = { LineStatMessage, "Line State Message", offsize(sccp_data_t, LineStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1896 [ConfigStatMessage] = { ConfigStatMessage, "Config State Message", offsize(sccp_data_t, ConfigStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1897 [ConfigStatDynamicMessage] = { ConfigStatDynamicMessage, "Config State Dynamic Message", offsize(sccp_data_t, ConfigStatDynamicMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1898 [DefineTimeDate] = { DefineTimeDate, "Define Time Date", offsize(sccp_data_t, DefineTimeDate), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1899 /**/[StartSessionTransmission] = { StartSessionTransmission, "Start Session Transmission", offsize(sccp_data_t, StartSessionTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1900 /**/[StopSessionTransmission] = { StopSessionTransmission, "Stop Session Transmission", offsize(sccp_data_t, StopSessionTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1901 [ButtonTemplateMessage] = { ButtonTemplateMessage, "Button Template Message", offsize(sccp_data_t, ButtonTemplateMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1902 //[ButtonTemplateMessageSingle] = {ButtonTemplateMessageSingle, "Button Template Message Single", offsize(sccp_data_t, ButtonTemplateMessageSingle)},
1903 [VersionMessage] = { VersionMessage, "Version Message", offsize(sccp_data_t, VersionMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1904 [DisplayTextMessage] = { DisplayTextMessage, "Display Text Message", offsize(sccp_data_t, DisplayTextMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1905 [ClearDisplay] = { ClearDisplay, "Clear Display", offsize(sccp_data_t, ClearDisplay), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1906
1907 [CapabilitiesReqMessage] = { CapabilitiesReqMessage, "Capabilities Request", offsize(sccp_data_t, CapabilitiesReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1908
1909 [EnunciatorCommandMessage] = { EnunciatorCommandMessage, "Enunciator Command Message", offsize(sccp_data_t, EnunciatorCommandMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1910 [RegisterRejectMessage] = { RegisterRejectMessage, "Register Reject Message", offsize(sccp_data_t, RegisterRejectMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1911 [ServerResMessage] = { ServerResMessage, "Server Response", offsize(sccp_data_t, ServerResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1912 [Reset] = { Reset, "Reset", offsize(sccp_data_t, Reset), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1913 [KeepAliveAckMessage] = { KeepAliveAckMessage, "Keep Alive Acknowledge", offsize(sccp_data_t, KeepAliveAckMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1914 /**/[StartMulticastMediaReception] = { StartMulticastMediaReception, "Start MulticastMedia Reception", offsize(sccp_data_t, StartMulticastMediaReception), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1915 /**/[StartMulticastMediaTransmission] = { StartMulticastMediaTransmission, "Start MulticastMedia Transmission", offsize(sccp_data_t, StartMulticastMediaTransmission), SKINNY_MSGTYPE_EVENT,
1916 SKINNY_MSGDIRECTION_PBX2DEV },
1917 /**/[StopMulticastMediaReception] = { StopMulticastMediaReception, "Stop MulticastMedia Reception", offsize(sccp_data_t, StopMulticastMediaReception), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1918 /**/[StopMulticastMediaTransmission] = { StopMulticastMediaTransmission, "Stop MulticastMedia Transmission", offsize(sccp_data_t, StopMulticastMediaTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1919 [OpenReceiveChannel] = { OpenReceiveChannel, "Open Receive Channel", offsize(sccp_data_t, OpenReceiveChannel), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1920 [CloseReceiveChannel] = { CloseReceiveChannel, "Close Receive Channel", offsize(sccp_data_t, CloseReceiveChannel), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1921 /*[ConnectionStatisticsReq] = { ConnectionStatisticsReq, "Connection Statistics Request", offsize(sccp_data_t, ConnectionStatisticsReq), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },**/
1922 [ConnectionStatisticsReq] = { ConnectionStatisticsReq, "Connection Statistics Request", offsize(sccp_data_t, ConnectionStatisticsReq), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1923 [SoftKeyTemplateResMessage] = { SoftKeyTemplateResMessage, "SoftKey Template Response", offsize(sccp_data_t, SoftKeyTemplateResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1924 [SoftKeySetResMessage] = { SoftKeySetResMessage, "SoftKey Set Response", offsize(sccp_data_t, SoftKeySetResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1925 [SelectSoftKeysMessage] = { SelectSoftKeysMessage, "Select SoftKeys Message", offsize(sccp_data_t, SelectSoftKeysMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1926 [CallStateMessage] = { CallStateMessage, "Call State Message", offsize(sccp_data_t, CallStateMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1927 [DisplayPromptStatusMessage] = { DisplayPromptStatusMessage, "Display Prompt Status Message", offsize(sccp_data_t, DisplayPromptStatusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1928 [ClearPromptStatusMessage] = { ClearPromptStatusMessage, "Clear Prompt Status Message", offsize(sccp_data_t, ClearPromptStatusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1929 [DisplayNotifyMessage] = { DisplayNotifyMessage, "Display Notify Message", offsize(sccp_data_t, DisplayNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1930 [ClearNotifyMessage] = { ClearNotifyMessage, "Clear Notify Message", offsize(sccp_data_t, ClearNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1931 [ActivateCallPlaneMessage] = { ActivateCallPlaneMessage, "Activate Call Plane Message", offsize(sccp_data_t, ActivateCallPlaneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1932 [DeactivateCallPlaneMessage] = { DeactivateCallPlaneMessage, "Deactivate Call Plane Message", offsize(sccp_data_t, DeactivateCallPlaneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1933 [UnregisterAckMessage] = { UnregisterAckMessage, "Unregister Acknowledge", offsize(sccp_data_t, UnregisterAckMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1934 [BackSpaceResMessage] = { BackSpaceResMessage, "Back Space Response", offsize(sccp_data_t, BackSpaceResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1935 [RegisterTokenAck] = { RegisterTokenAck, "Register Token Acknowledge", offsize(sccp_data_t, RegisterTokenAck), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1936 [RegisterTokenReject] = { RegisterTokenReject, "Register Token Reject", offsize(sccp_data_t, RegisterTokenReject), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1937 [StartMediaFailureDetection] = { StartMediaFailureDetection, "Start Media Failure Detection", offsize(sccp_data_t, StartMediaFailureDetection), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1938 [DialedNumberMessage] = { DialedNumberMessage, "Dialed Number Message", offsize(sccp_data_t, DialedNumberMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1939 [UserToDeviceDataMessage] = { UserToDeviceDataMessage, "User To Device Data Message", offsize(sccp_data_t, UserToDeviceDataMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1940 [FeatureStatMessage] = { FeatureStatMessage, "Feature State Message", offsize(sccp_data_t, FeatureStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1941 [DisplayPriNotifyMessage] = { DisplayPriNotifyMessage, "Display Pri Notify Message", offsize(sccp_data_t, DisplayPriNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1942 [ClearPriNotifyMessage] = { ClearPriNotifyMessage, "Clear Pri Notify Message", offsize(sccp_data_t, ClearPriNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1943 [StartAnnouncementMessage] = { StartAnnouncementMessage, "Start Announcement Message", offsize(sccp_data_t, StartAnnouncementMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1944 [StopAnnouncementMessage] = { StopAnnouncementMessage, "Stop Announcement Message", offsize(sccp_data_t, StopAnnouncementMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1945 [AnnouncementFinishMessage] = { AnnouncementFinishMessage, "Announcement Finish Message", offsize(sccp_data_t, AnnouncementFinishMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1946 [NotifyDtmfToneMessage] = { NotifyDtmfToneMessage, "Notify DTMF Tone Message", offsize(sccp_data_t, NotifyDtmfToneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1947 [SendDtmfToneMessage] = { SendDtmfToneMessage, "Send DTMF Tone Message", offsize(sccp_data_t, SendDtmfToneMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1948 [SubscribeDtmfPayloadReqMessage] = { SubscribeDtmfPayloadReqMessage, "Subscribe DTMF Payload Request", offsize(sccp_data_t, SubscribeDtmfPayloadReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1949 [SubscribeDtmfPayloadResMessage] = { SubscribeDtmfPayloadResMessage, "Subscribe DTMF Payload Response", offsize(sccp_data_t, SubscribeDtmfPayloadResMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_DEV2PBX },
1950 [SubscribeDtmfPayloadErrMessage] = { SubscribeDtmfPayloadErrMessage, "Subscribe DTMF Payload Error Message", offsize(sccp_data_t, SubscribeDtmfPayloadErrMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1951 [UnSubscribeDtmfPayloadReqMessage] = { UnSubscribeDtmfPayloadReqMessage, "UnSubscribe DTMF Payload Request", offsize(sccp_data_t, UnSubscribeDtmfPayloadReqMessage), SKINNY_MSGTYPE_REQUEST,
1952 SKINNY_MSGDIRECTION_UNKNOWN },
1953 [UnSubscribeDtmfPayloadResMessage] = { UnSubscribeDtmfPayloadResMessage, "UnSubscribe DTMF Payload Response", offsize(sccp_data_t, UnSubscribeDtmfPayloadResMessage), SKINNY_MSGTYPE_RESPONSE,
1954 SKINNY_MSGDIRECTION_UNKNOWN },
1955 [UnSubscribeDtmfPayloadErrMessage] = { UnSubscribeDtmfPayloadErrMessage, "UnSubscribe DTMF Payload Error Message", offsize(sccp_data_t, UnSubscribeDtmfPayloadErrMessage), SKINNY_MSGTYPE_EVENT,
1956 SKINNY_MSGDIRECTION_UNKNOWN },
1957 [ServiceURLStatMessage] = { ServiceURLStatMessage, "ServiceURL State Message", offsize(sccp_data_t, ServiceURLStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1958 [CallSelectStatMessage] = { CallSelectStatMessage, "Call Select State Message", offsize(sccp_data_t, CallSelectStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1959 [OpenMultiMediaChannelMessage] = { OpenMultiMediaChannelMessage, "Open MultiMedia Channel Message", offsize(sccp_data_t, OpenMultiMediaChannelMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1960 /*spa*/[StartMultiMediaTransmission] = { StartMultiMediaTransmission, "Start MultiMedia Transmission", offsize(sccp_data_t, StartMultiMediaTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1961 /**/[StopMultiMediaTransmission] = { StopMultiMediaTransmission, "Stop MultiMedia Transmission", offsize(sccp_data_t, StopMultiMediaTransmission), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1962 [MiscellaneousCommandMessage] = { MiscellaneousCommandMessage, "Miscellaneous Command Message", offsize(sccp_data_t, MiscellaneousCommandMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1963 [FlowControlCommandMessage] = { FlowControlCommandMessage, "Flow Control Command Message", offsize(sccp_data_t, FlowControlCommandMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1964 [CloseMultiMediaReceiveChannel] = { CloseMultiMediaReceiveChannel, "Close MultiMedia Receive Channel", offsize(sccp_data_t, CloseMultiMediaReceiveChannel), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1965 [CreateConferenceReqMessage] = { CreateConferenceReqMessage, "Create Conference Request", offsize(sccp_data_t, CreateConferenceReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1966 [DeleteConferenceReqMessage] = { DeleteConferenceReqMessage, "Delete Conference Request", offsize(sccp_data_t, DeleteConferenceReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1967 [ModifyConferenceReqMessage] = { ModifyConferenceReqMessage, "Modify Conference Request", offsize(sccp_data_t, ModifyConferenceReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1968 [AddParticipantReqMessage] = { AddParticipantReqMessage, "Add Participant Request", offsize(sccp_data_t, AddParticipantReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1969 [DropParticipantReqMessage] = { DropParticipantReqMessage, "Drop Participant Request", offsize(sccp_data_t, DropParticipantReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1970 [AuditConferenceReqMessage] = { AuditConferenceReqMessage, "Audit Conference Request", offsize(sccp_data_t, AuditConferenceReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1971 [AuditParticipantReqMessage] = { AuditParticipantReqMessage, "Audit Participant Request", offsize(sccp_data_t, AuditParticipantReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1972 [UserToDeviceDataVersion1Message] = { UserToDeviceDataVersion1Message, "User To Device Data Version1 Message", offsize(sccp_data_t, UserToDeviceDataVersion1Message), SKINNY_MSGTYPE_EVENT,
1973 SKINNY_MSGDIRECTION_PBX2DEV },
1974 [DisplayDynamicNotifyMessage] = { DisplayDynamicNotifyMessage, "Display Dynamic Notify Message", offsize(sccp_data_t, DisplayDynamicNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1975 [DisplayDynamicPriNotifyMessage] = { DisplayDynamicPriNotifyMessage, "Display Dynamic Priority Notify Message", offsize(sccp_data_t, DisplayDynamicPriNotifyMessage), SKINNY_MSGTYPE_EVENT,
1976 SKINNY_MSGDIRECTION_UNKNOWN },
1977 [DisplayDynamicPromptStatusMessage] = { DisplayDynamicPromptStatusMessage, "Display Dynamic Prompt Status Message", offsize(sccp_data_t, DisplayDynamicPromptStatusMessage), SKINNY_MSGTYPE_EVENT,
1978 SKINNY_MSGDIRECTION_UNKNOWN },
1979 [FeatureStatDynamicMessage] = { FeatureStatDynamicMessage, "SpeedDial State Dynamic Message", offsize(sccp_data_t, FeatureStatDynamicMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1980 [LineStatDynamicMessage] = { LineStatDynamicMessage, "Line State Dynamic Message", offsize(sccp_data_t, LineStatDynamicMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1981 [ServiceURLStatDynamicMessage] = { ServiceURLStatDynamicMessage, "Service URL Stat Dynamic Messages", offsize(sccp_data_t, ServiceURLStatDynamicMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1982 [SpeedDialStatDynamicMessage] = { SpeedDialStatDynamicMessage, "SpeedDial Stat Dynamic Message", offsize(sccp_data_t, SpeedDialStatDynamicMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1983 [CallInfoDynamicMessage] = { CallInfoDynamicMessage, "Call Information Dynamic Message", offsize(sccp_data_t, CallInfoDynamicMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1984 [SubscriptionStatMessage] = { SubscriptionStatMessage, "Subscription Status Response (Dialed Number)", offsize(sccp_data_t, SubscriptionStatMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
1985 [NotificationMessage] = { NotificationMessage, "Notify Call List (CallListStatusUpdate)", offsize(sccp_data_t, NotificationMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1986 /*spa*/[StartMediaTransmissionAck] = { StartMediaTransmissionAck, "Start Media Transmission Acknowledge", offsize(sccp_data_t, StartMediaTransmissionAck), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1987 /**/[StartMultiMediaTransmissionAck] = { StartMultiMediaTransmissionAck, "Start Media Transmission Acknowledge", offsize(sccp_data_t, StartMultiMediaTransmissionAck), SKINNY_MSGTYPE_EVENT,
1988 SKINNY_MSGDIRECTION_PBX2DEV },
1989 [CallHistoryDispositionMessage] = { CallHistoryDispositionMessage, "Call History Disposition", offsize(sccp_data_t, CallHistoryDispositionMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1990 [LocationInfoMessage] = { LocationInfoMessage, "Location/Wifi Information", offsize(sccp_data_t, LocationInfoMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1991 [ExtensionDeviceCaps] = { ExtensionDeviceCaps, "Extension Device Capabilities Message", offsize(sccp_data_t, ExtensionDeviceCaps), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1992 [XMLAlarmMessage] = { XMLAlarmMessage, "XML-AlarmMessage", offsize(sccp_data_t, XMLAlarmMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1993 [MediaPathCapabilityMessage] = { MediaPathCapabilityMessage, "MediaPath Capability Message", offsize(sccp_data_t, MediaPathCapabilityMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1994 [FlowControlNotifyMessage] = { FlowControlNotifyMessage, "FlowControl Notify Message", offsize(sccp_data_t, FlowControlNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
1995 [CallCountReqMessage] = { CallCountReqMessage, "CallCount Request Message", offsize(sccp_data_t, CallCountReqMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
1996 /*new*/
1997 [UpdateCapabilitiesV2Message] = { UpdateCapabilitiesV2Message, "Update Capabilities V2", offsize(sccp_data_t, UpdateCapabilitiesV2Message), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1998 [UpdateCapabilitiesV3Message] = { UpdateCapabilitiesV3Message, "Update Capabilities V3", offsize(sccp_data_t, UpdateCapabilitiesV3Message), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_DEV2PBX },
1999 [PortResponseMessage] = { PortResponseMessage, "Port Response Message", offsize(sccp_data_t, PortResponseMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
2000 [QoSResvNotifyMessage] = { QoSResvNotifyMessage, "QoS Resv Notify Message", offsize(sccp_data_t, QoSResvNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2001 [QoSErrorNotifyMessage] = { QoSErrorNotifyMessage, "QoS Error Notify Message", offsize(sccp_data_t, QoSErrorNotifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2002 [PortRequestMessage] = { PortRequestMessage, "Port Request Message", offsize(sccp_data_t, PortRequestMessage), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_PBX2DEV },
2003 [PortCloseMessage] = { PortCloseMessage, "Port Close Message", offsize(sccp_data_t, PortCloseMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2004 [QoSListenMessage] = { QoSListenMessage, "QoS Listen Message", offsize(sccp_data_t, QoSListenMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2005 [QoSPathMessage] = { QoSPathMessage, "QoS Path Message", offsize(sccp_data_t, QoSPathMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2006 [QoSTeardownMessage] = { QoSTeardownMessage, "QoS Teardown Message", offsize(sccp_data_t, QoSTeardownMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2007 [UpdateDSCPMessage] = { UpdateDSCPMessage, "Update DSCP Message", offsize(sccp_data_t, UpdateDSCPMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2008 [QoSModifyMessage] = { QoSModifyMessage, "QoS Modify Message", offsize(sccp_data_t, QoSModifyMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2009 [MwiResponseMessage] = { MwiResponseMessage, "Mwi Response Message", offsize(sccp_data_t, MwiResponseMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
2010 [CallCountRespMessage] = { CallCountRespMessage, "CallCount Response Message", offsize(sccp_data_t, CallCountRespMessage), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
2011 [RecordingStatusMessage] = { RecordingStatusMessage, "Recording Status Message", offsize(sccp_data_t, RecordingStatusMessage), SKINNY_MSGTYPE_EVENT, SKINNY_MSGDIRECTION_PBX2DEV },
2012 /* clang-format on */
2013 };
2014
2015 const struct messageinfo spcp_messageinfo[] = {
2016 /* clang-format off */
2017 [SPCPRegisterTokenRequest - SPCP_MESSAGE_OFFSET] = { SPCPRegisterTokenRequest, "SPCP Register Token Request", offsize(sccp_data_t, SPCPRegisterTokenRequest), SKINNY_MSGTYPE_REQUEST, SKINNY_MSGDIRECTION_DEV2PBX },
2018 [SPCPRegisterTokenAck - SPCP_MESSAGE_OFFSET] = { SPCPRegisterTokenAck, "SPCP RegisterMessageACK", offsize(sccp_data_t, SPCPRegisterTokenAck), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
2019 [SPCPRegisterTokenReject - SPCP_MESSAGE_OFFSET] = { SPCPRegisterTokenReject, "SPCP RegisterMessageReject", offsize(sccp_data_t, SPCPRegisterTokenReject), SKINNY_MSGTYPE_RESPONSE, SKINNY_MSGDIRECTION_PBX2DEV },
2020 //[UnknownVGMessage - SPCP_MESSAGE_OFFSET ] = {UnknownVGMessage, "Unknown Message (VG224)", offsize(sccp_data_t, UnknownVGMessage)},
2021 /* clang-format on */
2022 };
2023
lookupMsgInfoStruct(uint32_t messageId)2024 gcc_inline struct messageinfo * lookupMsgInfoStruct(uint32_t messageId)
2025 {
2026 if(messageId <= SCCP_MESSAGE_HIGH_BOUNDARY) {
2027 return (struct messageinfo *)&sccp_messageinfo[messageId];
2028 }
2029 if(messageId >= SPCP_MESSAGE_LOW_BOUNDARY && messageId <= SPCP_MESSAGE_HIGH_BOUNDARY) {
2030 return (struct messageinfo *)&spcp_messageinfo[messageId - SPCP_MESSAGE_OFFSET];
2031 }
2032 pbx_log(LOG_ERROR, "SCCP: (session::lookupMsgInfo) messageId out of bounds: %d < %u > %d. Or messageId unknown. discarding message.\n", SCCP_MESSAGE_LOW_BOUNDARY, messageId, SPCP_MESSAGE_HIGH_BOUNDARY);
2033 return NULL;
2034 }
2035
msginfo2str(sccp_mid_t msgId)2036 gcc_inline const char * msginfo2str(sccp_mid_t msgId)
2037 { /* sccp_protocol.h */
2038 struct messageinfo * info = lookupMsgInfoStruct(msgId);
2039 return info->text;
2040 }
2041
2042 // kate: indent-width 8; replace-tabs off; indent-mode cstyle; auto-insert-doxygen on; line-numbers on; tab-indents on; keep-extra-spaces off; auto-brackets off;
2043