void CameraHistoryUpdater::run()
{
    while (d->running)
    {
        {
            CHUpdateItem item;

            QMutexLocker lock(&d->mutex);

            if (!d->updateItems.isEmpty())
            {
                item = d->updateItems.takeFirst();
                sendBusy(true);
                proccessMap(item.first, item.second);
            }
            else
            {
                sendBusy(false);
                d->condVar.wait(&d->mutex);
                continue;
            }
        }
    }

    sendBusy(false);
}
Example #2
0
void* UserAgent::run(void* arg) {
	common = (Common *)arg;

	init(0);

	while(common->go) {
		memo = (Memo*)common->signalQ->waitForData(waitMSec);

		if(memo) switch(memo->code) {
			case VIVOCE_SIP_INVITE:
				if(state==SIP_UA_DISCONNECTED) {
					//printf("\n\tSending INVITE....");
					name = strtok_r(memo->bytes,"@",&temp);
					remoteId = (char*)malloc(strlen(name)+1);
					sprintf(remoteId,"%s",name);

					name = strtok_r(NULL,":",&temp);
					if(name) {
						remoteHost = (char*) malloc(strlen(name)+1);
						sprintf(remoteHost,"%s",name);
						name=name = strtok_r(NULL,":",&temp);
						if(name)
							remoteSipPort = atoi(name);
						else
							remoteSipPort = VIVOCE_SIP_PORT;
						sendInvite();
						common->reset();
					}
					else {
						printf("\n\tSIP: Malformed URI");
						common->sipRmg->releaseMemo(memo);
					}
				}
				else
					common->sipRmg->releaseMemo(memo);
				break;

			case VIVOCE_SIP_BYE:
				if(common->isConnected) {
					common->isConnected=0;
					printf("\n\tDisconnecting....");
					rptCount=0;
					sendBye();
				}
				else
					common->sipRmg->releaseMemo(memo);
				break;

			case VIVOCE_SIP_ACCEPT:
				if(state == SIP_UA_RCVD_INV) {
					//printf("\n\tSending OK....");
					sendOk();
					state = SIP_UA_ACCEPTED;
					common->isRinging=0;
				}
				else
					common->sipRmg->releaseMemo(memo);
				break;
			case VIVOCE_SIP_REJECT:
				if(state == SIP_UA_RCVD_INV) {
					//printf("\n\tSending DECLINE....");
					sendDecline();
					common->isRinging=0;
				}
				else
					common->sipRmg->releaseMemo(memo);
				break;

			case VIVOCE_SIP_RCVD:
			//incoming!!
			if(common->verbose) {
				printf("\n\tINFO: SIP Msg Recv=%d bytes:\n%s", memo->data1,memo->bytes);
			}
			sipPackRecv->reset();
			ret = SIPHandler::read(memo->bytes,
								memo->data1,
								sipPackRecv);
			if(ret<0) {
				printf("\n\tSIP: Error in parsing SIP packet");
			}
			else {
			if((!sipPackRecv->isRequest)
				&& (sipPackRecv->responseCode!=SIP_RESPONSE_OK)) {
				printf("\n\tSIP: Received response code %d.",
					sipPackRecv->responseCode);
			}
			switch(state) {
				case SIP_UA_DISCONNECTED:
				if((sipPackRecv->isRequest)
					&& (sipPackRecv->requestCode==SIP_METHOD_INV)) {
					checkPacket();
					if(discard) {
						printf("\n\tSIP: Incorrect SDP content: discarding");
						common->sipRmg->releaseMemo(memo);
						checkSrc=false;
					}
					else {
						callId = sipPackRecv->callId;
						callIdHost = (char*)malloc(strlen(sipPackRecv->callIdHost)+1);
						sprintf(callIdHost, "%s", sipPackRecv->callIdHost);
                        //memory leak in these mallocs, but fixing them with realloc causes segfaults! for now, waste these ~100 bytes...
						remoteId = (char*)malloc(strlen(sipPackRecv->contactUri.id)+1);
						sprintf(remoteId, "%s", sipPackRecv->contactUri.id);

						remoteHost = (char*)malloc(strlen(sipPackRecv->contactUri.host)+1);
						sprintf(remoteHost,"%s",
							sipPackRecv->contactUri.host);
						printf("\n\tSIP: Recvd invite from %s at %s!!!",
							sipPackRecv->contactUri.id,
							sipPackRecv->contactUri.host);
						printf("\n\tRing!!!");
						sendRinging();
						waitMSec=2500;
						state = SIP_UA_RCVD_INV;
						defaultAction = SIP_SEND_RING;
					}
				}
				else
					common->sipRmg->releaseMemo(memo);	//else discard
				break;

				case SIP_UA_SENT_INV:
				if((!sipPackRecv->isRequest)
					&& (sipPackRecv->callId == callId)
					&& (!strcmp(callIdHost,sipPackRecv->callIdHost))) {

					if(sipPackRecv->responseCode==SIP_RESPONSE_RING) {
						printf("\n\tSIP: Ringing callee....");
						common->isRinging=1;
						waitMSec=5000;
						defaultAction = SIP_CONN;
						//display ringing for some time
						common->sipRmg->releaseMemo(memo);
					}
					else if(sipPackRecv->responseCode==SIP_RESPONSE_BUSY) {
						printf("\n\tSIP: Callee is Busy! Try again later");
						waitMSec=500;
						defaultAction = SIP_DISCONN;
						common->sipRmg->releaseMemo(memo);
						common->isRinging=0;
					}
					else if(sipPackRecv->responseCode==SIP_RESPONSE_DECLINE) {
						printf("\n\tSIP: Callee has declined to accept your call");
						waitMSec=500;
						defaultAction = SIP_DISCONN;
						common->sipRmg->releaseMemo(memo);
						common->isRinging=0;
					}
					else if(sipPackRecv->responseCode==SIP_RESPONSE_OK) {
						checkPacket();
						if(discard) {
							printf("\n\tSIP: Incorrect SDP content: discarding");
							common->sipRmg->releaseMemo(memo);
							checkSrc=false;
						}
						else {
							if(common->verbose) {
								printf("\n\tINFO: Listening for RTP/RTCP on ports %d/%d",
									remoteRtpPort,
									remoteRtcpPort);
							}
							UdpBase::initRemoteAddr(common,
                    								remoteHost,
                    								remoteRtpPort,
                    								remoteRtcpPort,
                    								0);
							printf("\n\tSIP: Connected!!!");
							sendAck();
							common->isRinging=0;
						}
					}
					else
						checkSrc=true;
				}
				else
					checkSrc=true;
				break;

				case SIP_UA_SENT_BYE:
				if(!sipPackRecv->isRequest) {
					if(sipPackRecv->responseCode==SIP_RESPONSE_OK) {
						printf("\n\tSIP: Disconnect complete.");
						state = SIP_UA_DISCONNECTED;
						cleanup();
						defaultAction = SIP_NONE;
					}
					common->sipRmg->releaseMemo(memo);
				}
				else
					checkSrc=true;
				break;

				case SIP_UA_ACCEPTED:
				if(sipPackRecv->isRequest
					&& (sipPackRecv->requestCode== SIP_METHOD_ACK)
					&& (sipPackRecv->callId == callId)
					&& (!strcmp(callIdHost, sipPackRecv->callIdHost))) {
					//printf("\n\tSIP: Acknowledged....");
					common->isConnected = 1;
					common->rtpMgr->init(RTP_PAYLOAD_TYPE_ADPCM, const_cast<char*>("stats"));
					waitMSec=2500;
					defaultAction = SIP_NONE;
					state = SIP_UA_IN_CALL;
					common->sipRmg->releaseMemo(memo);
					common->isRinging=0;
				}
				else
					checkSrc=true;
				break;

				case SIP_UA_REJECTED:
				if(sipPackRecv->isRequest
					&& (sipPackRecv->requestCode== SIP_METHOD_ACK)
					&& (sipPackRecv->callId == callId)
					&& (!strcmp(callIdHost,sipPackRecv->callIdHost))) {
					//printf("\n\tSIP: Acknowledged....");
					common->isConnected=0;
					waitMSec=500;
					defaultAction = SIP_DISCONN;
					common->sipRmg->releaseMemo(memo);
					common->isRinging=0;
				}
				else
					checkSrc=true;
				break;

				case SIP_UA_IN_CALL:
				if(sipPackRecv->isRequest
					&& (sipPackRecv->requestCode==SIP_METHOD_BYE)
					&& (sipPackRecv->callId == callId)) {
					//printf("\n\tSending OK for BYE....");
					printf("\n\tSIP: Disconnected by peer.");
					sendOk();
					common->isConnected=0;
					waitMSec=2500;
					defaultAction = SIP_DISCONN;
					state = SIP_UA_DISCONNECTED;
				}
				else
					checkSrc=true;
				break;

				default:
					checkSrc=true;
				break;
			}
			if(checkSrc) {
				checkSrc=false;
				if(sipPackRecv->callId != callId) {
					//printf("\n\tSending BUSY");
					UdpBase::initTempRemoteAddr(common,
                        						sipPackRecv->contactUri.host,
                        						remoteSipPort);
					sendBusy();
				}
				else
					common->sipRmg->releaseMemo(memo);
			}
			break;
			}
			break;

			default:
				printf("\n\tSIP: In invalid state! %d",state);
				common->sipRmg->releaseMemo(memo);
				break;

			case VIVOCE_RESPOND:
				printf("\n\tUser Agent active - %d",state);
				common->sipRmg->releaseMemo(memo);
				break;
		}
		else
			doDefaultAction();

	}
	printf("UserAgent stopped. ");
	return NULL;
}